Fabric8 customResourceDefinitions 测试

Fabric8 customResourceDefinitions test

我正在进行 Fabric8 单元测试,现在我正在尝试针对 KubernetesServer 创建 CRD。

import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinition;

public class TestCertManagerService {

  @Rule
  public KubernetesServer server = new KubernetesServer();


  @Test
  @DisplayName("Should list all CronTab custom resources")
  public void testCronTabCrd() throws IOException {
    // Given
    //server.expect().get().withPath("/apis/stable.example.com/v1/namespaces/default/crontabs").andReturn(HttpURLConnection.HTTP_OK, ?????).once();
    KubernetesClient client = server.getClient();


    CustomResourceDefinition cronTabCrd = client.apiextensions().v1().customResourceDefinitions()
        .load(new BufferedInputStream(new FileInputStream("src/test/resources/crontab-crd.yml")))
        .get();
    client.apiextensions().v1().customResourceDefinitions().create(cronTabCrd);

  }
}

当我运行它时,我得到以下错误

TestCertManagerService > testCronTabCrd FAILED
    io.fabric8.kubernetes.client.KubernetesClientException: Failure executing: GET at: https://localhost:60690/apis/apiextensions.k8s.io/v1/customresourcedefinitions.
        at app//io.fabric8.kubernetes.client.dsl.base.OperationSupport.requestFailure(OperationSupport.java:694)
        at app//io.fabric8.kubernetes.client.dsl.base.OperationSupport.requestFailure(OperationSupport.java:673)
        at app//io.fabric8.kubernetes.client.dsl.base.OperationSupport.assertResponseCode(OperationSupport.java:626)
        at app//io.fabric8.kubernetes.client.dsl.base.OperationSupport.handleResponse(OperationSupport.java:566)
        at app//io.fabric8.kubernetes.client.dsl.base.OperationSupport.handleResponse(OperationSupport.java:527)
        at app//io.fabric8.kubernetes.client.dsl.base.OperationSupport.handleResponse(OperationSupport.java:510)
        at app//io.fabric8.kubernetes.client.dsl.base.BaseOperation.listRequestHelper(BaseOperation.java:136)
        at app//io.fabric8.kubernetes.client.dsl.base.BaseOperation.list(BaseOperation.java:505)
        at app//io.fabric8.kubernetes.client.dsl.base.BaseOperation.list(BaseOperation.java:494)
        at app//io.fabric8.kubernetes.client.dsl.base.BaseOperation.list(BaseOperation.java:87)
        at app//com.ibm.si.qradar.cp4s.service.certmanager.TestCertManagerService.testCronTabCrd(TestCertManagerService.java:94)

我有几个问题: (1) 在这种情况下,我使用的是 v1() 接口,有时我看到示例代码使用的是 v1beta1(),是什么决定了这个版本?对了,我用的是Kubernetes-client library 5.9.0

(2) 在我的代码中,我注释掉了这一行

server.expect().get().withPath("/apis/stable.example.com/v1/namespaces/default/crontabs").andReturn(HttpURLConnection.HTTP_OK, ?????).once();

这个语句是做什么用的?在我的例子中,我想加载一个 CRD,然后创建一个 CR,什么是“??????”在声明中?

  1. 对堆栈跟踪有什么想法吗?如何解决?

提前表示感谢

从您分享的代码来看,您似乎在期望模式下使用 Fabric8 Kubernetes Mock Server。期望模式要求用户设置 REST API 期望。因此,下面显示的代码从模拟服务器的角度设定了一些期望。

// Given
server.expect().get()
      .withPath("/apis/stable.example.com/v1/namespaces/default/crontabs")
      .andReturn(HttpURLConnection.HTTP_OK, getCronTabList())
      .once();

这些是设定的期望值:

  1. 模拟服务器将在 URL: /apis/stable.example.com/v1/namespaces/default/crontabs 被请求 GET 请求。从 URL 我们可以期望 stable.example.com apigroup 下的资源具有 v1 版本,default 命名空间和 crontabs 作为复数。
  2. 当这个 URL 被命中时,您也在 andReturn() 方法中定义响应代码和响应主体。第一个参数是响应代码(在本例中为 200),第二个参数是响应主体(CronTab 的 List 对象,它将被模拟服务器序列化并作为响应发送)。
  3. 如果Mock Server 创建的KubernetesClient 多次请求此端点,则此请求仅命中.once();测试会失败。如果你想多次命中终点,你可以使用 .times(..) 方法代替。

但在您的测试中,我看到您正在从 YAML 加载 CustomResourceDefinition 并创建它,这似乎与您之前设置的预期不符。如果您正在编写有关创建 CustomResourceDefinition 的测试,它应该如下所示:

@Test
@DisplayName("Should Create CronTab CRD")
void testCronTabCrd() throws IOException {
  // Given
  KubernetesClient client = server.getClient();
  CustomResourceDefinition cronTabCrd = client.apiextensions().v1()
    .customResourceDefinitions()
    .load(new BufferedInputStream(new FileInputStream("src/test/resources/crontab-crd.yml")))
    .get();
  server.expect().post()
    .withPath("/apis/apiextensions.k8s.io/v1/customresourcedefinitions")
    .andReturn(HttpURLConnection.HTTP_OK, cronTabCrd)
    .once();

  // When
  CustomResourceDefinition createdCronTabCrd = client.apiextensions().v1()
    .customResourceDefinitions()
    .create(cronTabCrd);

  // Then
  assertNotNull(createdCronTabCrd);
}

Bdw,如果您不喜欢设置 REST 期望。 Fabric8 Kubernetes Mock Server 也有一个模拟真实 Kubernetes APIServer 的 CRUD 模式。您可以像这样启用它:

@Rule
public KubernetesServer server = new KubernetesServer(true, true);

然后像这样在测试中使用它:

@Test
@DisplayName("Should Create CronTab CRD")
void testCronTabCrd() throws IOException {
  // Given
  KubernetesClient client = server.getClient();
  CustomResourceDefinition cronTabCrd = client.apiextensions().v1()
    .customResourceDefinitions()
    .load(new BufferedInputStream(new FileInputStream("src/test/resources/crontab-crd.yml")))
    .get();

  // When
  CustomResourceDefinition createdCronTabCrd = client.apiextensions().v1()
    .customResourceDefinitions()
    .create(cronTabCrd);

  // Then
  assertNotNull(createdCronTabCrd);
}

我加了CustomResourceLoadAndCreateTest and CustomResourceLoadAndCreateCrudTest tests in my demo repository: https://github.com/r0haaaan/kubernetes-mockserver-demo