fabric8io/kubernetes-client/WatchTest.java

本文介绍了一组针对 Kubernetes 客户端的 Watch 功能进行的测试案例,包括删除事件及过期状态处理、HTTP 错误情况下的重连机制等,通过模拟不同场景验证了客户端的稳定性和错误处理能力。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/**
  * Copyright (C) 2015 Red Hat, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
  * http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  
 package io.fabric8.kubernetes.client.mock;
  
 import static org.junit.Assert.assertTrue;
  
 import io.fabric8.kubernetes.api.model.Pod;
 import io.fabric8.kubernetes.api.model.PodBuilder;
 import io.fabric8.kubernetes.api.model.Status;
 import io.fabric8.kubernetes.api.model.StatusBuilder;
 import io.fabric8.kubernetes.api.model.WatchEvent;
 import io.fabric8.kubernetes.api.model.WatchEventBuilder;
 import io.fabric8.kubernetes.client.KubernetesClient;
 import io.fabric8.kubernetes.client.KubernetesClientException;
 import io.fabric8.kubernetes.client.Watch;
 import io.fabric8.kubernetes.client.Watcher;
 import io.fabric8.kubernetes.client.server.mock.KubernetesServer;
 import junit.framework.AssertionFailedError;
  
 import java.net.HttpURLConnection;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
  
 import org.junit.Rule;
 import org.junit.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
  
 public class WatchTest {
 Logger logger = LoggerFactory.getLogger(WatchTest.class);
  
 @Rule
 public KubernetesServer server = new KubernetesServer(false);
  
 static final Pod pod1 = new PodBuilder().withNewMetadata().withNamespace("test").withName("pod1")
 .withResourceVersion("1").endMetadata().build();
  
 static final Status outdatedStatus = new StatusBuilder().withCode(HttpURLConnection.HTTP_GONE)
 .withMessage(
 "401: The event in requested index is outdated and cleared (the requested history has been cleared [3/1]) [2]")
 .build();
 static final WatchEvent outdatedEvent = new WatchEventBuilder().withStatusObject(outdatedStatus).build();
  
 @Test
 public void testDeletedAndOutdated() throws InterruptedException {
 logger.info("testDeletedAndOutdated");
 KubernetesClient client = server.getClient().inNamespace("test");
  
 // DELETED event, then history outdated
 server.expect()
 .withPath("/api/v1/namespaces/test/pods?fieldSelector=metadata.name%3Dpod1&resourceVersion=1&watch=true")
 .andUpgradeToWebSocket().open().waitFor(2000).andEmit(new WatchEvent(pod1, "DELETED")).waitFor(2000)
 .andEmit(outdatedEvent).done().once();
  
 final CountDownLatch deleteLatch = new CountDownLatch(1);
 final CountDownLatch closeLatch = new CountDownLatch(1);
 try (Watch watch = client.pods().withName("pod1").withResourceVersion("1").watch(new Watcher<Pod>() {
 @Override
 public void eventReceived(Action action, Pod resource) {
 switch (action) {
 case DELETED:
 deleteLatch.countDown();
 break;
 default:
 throw new AssertionFailedError();
 }
 }
  
 @Override
 public void onClose(KubernetesClientException cause) {
 closeLatch.countDown();
 }
 })) /* autoclose */ {
 assertTrue(deleteLatch.await(10, TimeUnit.SECONDS));
 assertTrue(closeLatch.await(10, TimeUnit.SECONDS));
 }
 }
  
 @Test(expected = KubernetesClientException.class)
 public void testHttpErrorWithOutdated() {
 logger.info("testHttpErrorWithOutdated");
 KubernetesClient client = server.getClient().inNamespace("test");
 // http error: history outdated
 server.expect()
 .withPath("/api/v1/namespaces/test/pods?fieldSelector=metadata.name%3Dpod1&resourceVersion=1&watch=true")
 .andReturn(410, outdatedEvent).once();
 final boolean[] onCloseCalled = {false};
 try (Watch watch = client.pods().withName("pod1").withResourceVersion("1").watch(new Watcher<Pod>() {
 @Override
 public void eventReceived(Action action, Pod resource) {
 throw new AssertionFailedError();
 }
  
 @Override
 public void onClose(KubernetesClientException cause) {
 onCloseCalled[0] =true;
 }
 })) {
  
 }
 assertTrue(onCloseCalled[0]);
 }
  
 @Test
 public void testHttpErrorReconnect() throws InterruptedException {
 logger.info("testHttpErrorReconnect");
 String path = "/api/v1/namespaces/test/pods?fieldSelector=metadata.name%3Dpod1&resourceVersion=1&watch=true";
 KubernetesClient client = server.getClient().inNamespace("test");
 // accept watch and disconnect
 server.expect().withPath(path).andUpgradeToWebSocket().open().done().once();
 // refuse reconnect attempts 6 times
 server.expect().withPath(path).andReturn(503, new StatusBuilder().withCode(503).build()).times(6);
 // accept next reconnect and send outdated event to stop the watch
 server.expect().withPath(path).andUpgradeToWebSocket().open(outdatedEvent).done().once();
  
 final CountDownLatch closeLatch = new CountDownLatch(1);
 try (Watch watch = client.pods().withName("pod1").withResourceVersion("1").watch(new Watcher<Pod>() {
 @Override
 public void eventReceived(Action action, Pod resource) {
 throw new AssertionFailedError();
 }
  
 @Override
 public void onClose(KubernetesClientException cause) {
 logger.debug("onClose", cause);
 closeLatch.countDown();
 }
 })) /* autoclose */ {
 assertTrue(closeLatch.await(3, TimeUnit.MINUTES));
 }
 }
  
 @Test
 public void testOnCloseEvent() throws InterruptedException {
 logger.info("testOnCloseEvent");
 final CountDownLatch eventLatch = new CountDownLatch(2);
 final CountDownLatch closeLatch = new CountDownLatch(1);
 KubernetesClient client = server.getClient().inNamespace("test");
  
 server.expect()
 .withPath("/api/v1/namespaces/test/pods?fieldSelector=metadata.name%3Dpod1&resourceVersion=1&watch=true")
 .andUpgradeToWebSocket().open().waitFor(2000).andEmit(new WatchEvent(pod1, "MODIFIED")).waitFor(2000)
 .andEmit(new WatchEvent(pod1, "MODIFIED")).done().once();
  
 Watch watch = client.pods().withName("pod1").withResourceVersion("1").watch(new Watcher<Pod>() {
 @Override
 public void eventReceived(Action action, Pod resource) {
 eventLatch.countDown();
 }
  
 @Override
 public void onClose(KubernetesClientException cause) {
 closeLatch.countDown();
 }
 });
  
 assertTrue(eventLatch.await(10, TimeUnit.SECONDS));
 watch.close();
 assertTrue(closeLatch.await(10, TimeUnit.SECONDS));
 }
  
 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值