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]

Reply via email to