|
26 | 26 | import io.fabric8.kubernetes.api.model.Pod;
|
27 | 27 | import io.fabric8.kubernetes.api.model.PodBuilder;
|
28 | 28 | import io.fabric8.kubernetes.api.model.PodListBuilder;
|
| 29 | +import io.fabric8.kubernetes.api.model.Service; |
29 | 30 | import io.fabric8.kubernetes.api.model.Status;
|
30 | 31 | import io.fabric8.kubernetes.api.model.StatusBuilder;
|
31 | 32 | import io.fabric8.kubernetes.api.model.WatchEvent;
|
|
36 | 37 | import io.fabric8.kubernetes.api.model.rbac.ClusterRoleBindingBuilder;
|
37 | 38 | import io.fabric8.kubernetes.client.CustomResourceList;
|
38 | 39 | import io.fabric8.kubernetes.client.KubernetesClient;
|
| 40 | +import io.fabric8.kubernetes.client.KubernetesClientException; |
39 | 41 | import io.fabric8.kubernetes.client.Watcher;
|
| 42 | +import io.fabric8.kubernetes.client.WatcherException; |
40 | 43 | import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext;
|
41 | 44 | import io.fabric8.kubernetes.client.dsl.base.ResourceDefinitionContext;
|
42 | 45 | import io.fabric8.kubernetes.client.informers.ResourceEventHandler;
|
|
65 | 68 | import java.util.concurrent.ExecutionException;
|
66 | 69 | import java.util.concurrent.Future;
|
67 | 70 | import java.util.concurrent.TimeUnit;
|
| 71 | +import java.util.concurrent.TimeoutException; |
68 | 72 | import java.util.function.BiFunction;
|
69 | 73 | import java.util.function.Function;
|
70 | 74 |
|
@@ -897,6 +901,51 @@ public void onDelete(Pod oldObj, boolean deletedFinalStateUnknown) {
|
897 | 901 | assertFalse(podInformer.isRunning());
|
898 | 902 | }
|
899 | 903 |
|
| 904 | + @Test |
| 905 | + void testTerminalException() throws InterruptedException, TimeoutException { |
| 906 | + // should be an initial 404 |
| 907 | + SharedIndexInformer<Pod> informer = client.pods().runnableInformer(0); |
| 908 | + try { |
| 909 | + informer.run(); |
| 910 | + } catch (Exception e) { |
| 911 | + } |
| 912 | + try { |
| 913 | + informer.stopped().get(10, TimeUnit.SECONDS); |
| 914 | + } catch (ExecutionException e) { |
| 915 | + assertTrue(e.getCause() instanceof KubernetesClientException); |
| 916 | + } |
| 917 | + |
| 918 | + String startResourceVersion = "1000"; |
| 919 | + |
| 920 | + // initial list |
| 921 | + server.expect().withPath("/api/v1/pods") |
| 922 | + .andReturn(200, new PodListBuilder().withNewMetadata().withResourceVersion(startResourceVersion).endMetadata() |
| 923 | + .withItems(Collections.emptyList()).build()) |
| 924 | + .once(); |
| 925 | + |
| 926 | + // initial watch - terminates with an exception |
| 927 | + server.expect().withPath("/api/v1/pods?resourceVersion=" + startResourceVersion + "&allowWatchBookmarks=true&watch=true") |
| 928 | + .andUpgradeToWebSocket() |
| 929 | + .open() |
| 930 | + .waitFor(WATCH_EVENT_EMIT_TIME) |
| 931 | + .andEmit(new WatchEvent(new Service(), "ADDED")) // not a pod |
| 932 | + .waitFor(OUTDATED_WATCH_EVENT_EMIT_TIME) |
| 933 | + .andEmit(outdatedEvent) |
| 934 | + .done().always(); |
| 935 | + |
| 936 | + // When |
| 937 | + informer = client.pods().inAnyNamespace().runnableInformer(0); |
| 938 | + try { |
| 939 | + informer.run(); |
| 940 | + } catch (Exception e) { |
| 941 | + } |
| 942 | + try { |
| 943 | + informer.stopped().get(10, TimeUnit.SECONDS); |
| 944 | + } catch (ExecutionException e) { |
| 945 | + assertTrue(e.getCause() instanceof WatcherException); |
| 946 | + } |
| 947 | + } |
| 948 | + |
900 | 949 | @Test
|
901 | 950 | void testRunAfterStop() {
|
902 | 951 | // Given
|
|
0 commit comments