cdmikechen opened a new issue, #956: URL: https://github.com/apache/submarine/issues/956
At present, submarine's tests on k8s services are mainly in `submarine-k8s` packages. Because k8s service is a complex service composition, it is difficult to write unit tests of many k8s related functions (like `submarine-server-submitter` package) in a simple way. I think that since most of the methods in `submarine-server-submitter` package are processed by k8s API similar to CRUD, it should be necessary to keep/create enough test cases to test and verify these methods. I have just search some k8s client related test cases informations. In fact, I think the main problem is how to support a mock server, so that we can break away from the constraints of k8s and write test cases freely. I think in this issue https://github.com/kubernetes-client/java/issues/1842 we can get some inspiration. Most of k8s api can simulate the return message based on the http request, so we can refer to the methods mentioned in it to change the existing test cases. ### Mock Client and Server I've write a test case about how to test k8s client by a mock client and server ([WireMockRule](https://wiremock.org/)). It refers to [k8s java official test case](https://github.com/kubernetes-client/java/blob/master/extended/src/test/java/io/kubernetes/client/extended/kubectl/KubectlApplyTest.java) The following codes can be found in <https://github.com/shangyuantech/submarine/blob/SUBMARINE-1174/submarine-server/server-submitter/submitter-k8s/src/test/java/org/apache/submarine/server/submitter/k8s/SubmitterK8sMockApiTest.java> ```java public class SubmitterK8sMockApiTest { private K8sClient k8sClient; @Rule public WireMockRule wireMockRule = K8sMockClient.getWireMockRule(); @Before public void setup() throws IOException { this.k8sClient = new K8sMockClient(post(urlPathEqualTo("/api/v1/namespaces/foo/configmaps")) .withHeader("Content-Type", new EqualToPattern("application/json; charset=UTF-8")) .willReturn( aResponse() .withStatus(200) .withBody("{\"metadata\":{\"name\":\"bar\",\"namespace\":\"foo\"}}"))); } @Test public void testApplyConfigMap() { V1ConfigMap configMap = new V1ConfigMap() .apiVersion("v1") .metadata(new V1ObjectMeta().namespace("foo").name("bar")) .data(Collections.singletonMap("key1", "value1")); KubernetesApiResponse<V1ConfigMap> configMapResp = k8sClient.getConfigMapClient().create(configMap); V1ConfigMap rtnConfigmap = configMapResp.getObject(); assertNotNull(rtnConfigmap); assertEquals(rtnConfigmap.getMetadata().getNamespace(), "foo"); assertEquals(rtnConfigmap.getMetadata().getName(), "bar"); } } ``` In this case, I create a `K8sMockClient`. In this class I did some initialization of URL and WireMockRule for the client. The following codes can be found in <https://github.com/shangyuantech/submarine/blob/SUBMARINE-1174/submarine-server/server-submitter/submitter-k8s/src/test/java/org/apache/submarine/server/submitter/k8s/client/K8sMockClient.java> ```java private static String getResourceFileContent(String resource) { File file = new File(Objects.requireNonNull( K8sMockClient.class.getClassLoader().getResource(resource)).getPath() ); try { return new String(Files.readAllBytes(Paths.get(file.toString()))); } catch (IOException e) { e.printStackTrace(); return null; } } private static final String DISCOVERY_API = getResourceFileContent("client/discovery-api.json"); private static final String DISCOVERY_APIV1 = getResourceFileContent("client/discovery-api-v1.json"); private static final String DISCOVERY_APIS = getResourceFileContent("client/discovery-apis.json"); private static final WireMockRule wireMockRule = new WireMockRule(8384); public static WireMockRule getWireMockRule() { return wireMockRule; } public K8sMockClient() throws IOException { apiClient = new ClientBuilder().setBasePath("http://localhost:" + 8384).build(); wireMockRule.stubFor( get(urlPathEqualTo("/api")) .willReturn( aResponse() .withStatus(200) .withBody(DISCOVERY_API))); wireMockRule.stubFor( get(urlPathEqualTo("/apis")) .willReturn( aResponse() .withStatus(200) .withBody(DISCOVERY_APIS))); wireMockRule.stubFor( get(urlPathEqualTo("/api/v1")) .willReturn( aResponse() .withStatus(200) .withBody(DISCOVERY_APIV1))); coreApi = new CoreV1Api(); appsV1Api = new AppsV1Api(); customObjectsApi = new CustomObjectsApi(); configMapClient = new GenericKubernetesApi<>( V1ConfigMap.class, V1ConfigMapList.class, "", "v1", "configmaps", apiClient); } public K8sMockClient(MappingBuilder... mappingBuilders) throws IOException { this(); addMappingBuilders(mappingBuilders); } public void addMappingBuilders(MappingBuilder... mappingBuilders) { // add MappingBuilder to WireMockRule for (MappingBuilder mappingBuilder : mappingBuilders) { wireMockRule.stubFor(mappingBuilder); } } ``` -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
