4
4
package oracle .kubernetes .operator ;
5
5
6
6
import java .math .BigInteger ;
7
+ import java .util .List ;
7
8
import java .util .concurrent .atomic .AtomicBoolean ;
8
9
import java .util .function .Function ;
9
10
11
+ import io .kubernetes .client .openapi .ApiException ;
12
+ import io .kubernetes .client .openapi .models .V1ContainerState ;
13
+ import io .kubernetes .client .openapi .models .V1ContainerStateTerminated ;
14
+ import io .kubernetes .client .openapi .models .V1ContainerStateWaiting ;
15
+ import io .kubernetes .client .openapi .models .V1ContainerStatus ;
10
16
import io .kubernetes .client .openapi .models .V1ObjectMeta ;
11
17
import io .kubernetes .client .openapi .models .V1Pod ;
12
18
import io .kubernetes .client .openapi .models .V1PodCondition ;
24
30
25
31
import static oracle .kubernetes .operator .LabelConstants .CREATEDBYOPERATOR_LABEL ;
26
32
import static oracle .kubernetes .operator .LabelConstants .DOMAINUID_LABEL ;
33
+ import static oracle .kubernetes .operator .helpers .LegalNames .DOMAIN_INTROSPECTOR_JOB_SUFFIX ;
34
+ import static oracle .kubernetes .operator .logging .MessageKeys .INTROSPECTOR_POD_FAILED ;
35
+ import static oracle .kubernetes .utils .LogMatcher .containsInfo ;
27
36
import static org .hamcrest .Matchers .both ;
28
37
import static org .hamcrest .Matchers .hasEntry ;
29
38
import static org .hamcrest .Matchers .is ;
@@ -37,12 +46,30 @@ public class PodWatcherTest extends WatcherTestBase implements WatchListener<V1P
37
46
private static final String NAME = "test" ;
38
47
private KubernetesTestSupport testSupport = new KubernetesTestSupport ();
39
48
private final TerminalStep terminalStep = new TerminalStep ();
49
+ private java .util .List <com .meterware .simplestub .Memento > mementos = new java .util .ArrayList <>();
50
+ private java .util .List <java .util .logging .LogRecord > logRecords = new java .util .ArrayList <>();
40
51
41
52
@ Override
42
53
@ Before
43
54
public void setUp () throws Exception {
44
- super .setUp ();
55
+ mementos .add (StubWatchFactory .install ());
56
+ StubWatchFactory .setListener (this );
45
57
addMemento (testSupport .install ());
58
+ mementos .add (
59
+ oracle .kubernetes .utils .TestUtils .silenceOperatorLogger ()
60
+ .collectLogMessages (logRecords , getMessageKeys ())
61
+ .withLogLevel (java .util .logging .Level .FINE )
62
+ .ignoringLoggedExceptions (ApiException .class ));
63
+ }
64
+
65
+ private String [] getMessageKeys () {
66
+ return new String [] {
67
+ getPodFailedMessageKey ()
68
+ };
69
+ }
70
+
71
+ private String getPodFailedMessageKey () {
72
+ return INTROSPECTOR_POD_FAILED ;
46
73
}
47
74
48
75
@ Override
@@ -91,6 +118,10 @@ private V1Pod createPod() {
91
118
return new V1Pod ().metadata (new V1ObjectMeta ().namespace (NS ).name (NAME ));
92
119
}
93
120
121
+ private V1Pod createIntrospectorPod () {
122
+ return new V1Pod ().metadata (new V1ObjectMeta ().namespace (NS ).name (NAME + DOMAIN_INTROSPECTOR_JOB_SUFFIX ));
123
+ }
124
+
94
125
@ Test
95
126
public void whenPodInitiallyReady_waitForReadyProceedsImmediately () {
96
127
AtomicBoolean stopping = new AtomicBoolean (false );
@@ -116,6 +147,24 @@ private V1Pod markPodReady(V1Pod pod) {
116
147
return pod .status (new V1PodStatus ().phase ("Running" ).addConditionsItem (createCondition ("Ready" )));
117
148
}
118
149
150
+ private V1Pod addContainerStateWaitingMessage (V1Pod pod ) {
151
+ return pod .status (new V1PodStatus ()
152
+ .containerStatuses (java .util .Collections .singletonList (
153
+ new V1ContainerStatus ()
154
+ .ready (false )
155
+ .state (new V1ContainerState ().waiting (
156
+ new V1ContainerStateWaiting ().message ("Error" ))))));
157
+ }
158
+
159
+ private V1Pod addContainerStateTerminatedReason (V1Pod pod ) {
160
+ return pod .status (new V1PodStatus ()
161
+ .containerStatuses (java .util .Collections .singletonList (
162
+ new V1ContainerStatus ()
163
+ .ready (false )
164
+ .state (new V1ContainerState ().terminated (
165
+ new V1ContainerStateTerminated ().reason ("Error" ))))));
166
+ }
167
+
119
168
@ SuppressWarnings ("SameParameterValue" )
120
169
private V1PodCondition createCondition (String type ) {
121
170
return new V1PodCondition ().type (type ).status ("True" );
@@ -198,6 +247,22 @@ public void whenPodNotReadyLaterAndThenReady_runNextStep() {
198
247
assertThat (terminalStep .wasRun (), is (true ));
199
248
}
200
249
250
+ @ Test
251
+ public void whenIntrospectPodNotReadyWithTerminatedReason_logPodStatus () {
252
+ sendIntrospectorPodModifiedWatchAfterWaitForReady (this ::addContainerStateTerminatedReason );
253
+
254
+ assertThat (terminalStep .wasRun (), is (false ));
255
+ assertThat (logRecords , containsInfo (getPodFailedMessageKey ()));
256
+ }
257
+
258
+ @ Test
259
+ public void whenIntrospectPodNotReadyWithWaitingMessage_logPodStatus () {
260
+ sendIntrospectorPodModifiedWatchAfterWaitForReady (this ::addContainerStateWaitingMessage );
261
+
262
+ assertThat (terminalStep .wasRun (), is (false ));
263
+ assertThat (logRecords , containsInfo (getPodFailedMessageKey ()));
264
+ }
265
+
201
266
// Starts the waitForReady step with an incomplete pod and sends a watch indicating that the pod has changed
202
267
@ SafeVarargs
203
268
private void sendPodModifiedWatchAfterWaitForReady (Function <V1Pod ,V1Pod >... modifiers ) {
@@ -215,6 +280,23 @@ private void sendPodModifiedWatchAfterWaitForReady(Function<V1Pod,V1Pod>... modi
215
280
}
216
281
}
217
282
283
+ // Starts the waitForReady step with an incomplete pod and sends a watch indicating that the pod has changed
284
+ @ SafeVarargs
285
+ private void sendIntrospectorPodModifiedWatchAfterWaitForReady (Function <V1Pod ,V1Pod >... modifiers ) {
286
+ AtomicBoolean stopping = new AtomicBoolean (false );
287
+ PodWatcher watcher = createWatcher (stopping );
288
+ testSupport .defineResources (createIntrospectorPod ());
289
+
290
+ try {
291
+ testSupport .runSteps (watcher .waitForReady (createIntrospectorPod (), terminalStep ));
292
+ for (Function <V1Pod ,V1Pod > modifier : modifiers ) {
293
+ watcher .receivedResponse (new Watch .Response <>("MODIFIED" , modifier .apply (createIntrospectorPod ())));
294
+ }
295
+ } finally {
296
+ stopping .set (true );
297
+ }
298
+ }
299
+
218
300
@ Test
219
301
public void whenPodDeletedOnFirstRead_runNextStep () {
220
302
AtomicBoolean stopping = new AtomicBoolean (false );
0 commit comments