You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by ni...@apache.org on 2019/08/05 14:47:42 UTC

[servicecomb-pack] 31/38: SCB-1369 Add unit test cases for APIControllerV1

This is an automated email from the ASF dual-hosted git repository.

ningjiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-pack.git

commit b78efa78608b3d8d5dbbdebb871390ec3a322dce
Author: Lei Zhang <co...@gmail.com>
AuthorDate: Sat Aug 3 00:08:22 2019 +0800

    SCB-1369 Add unit test cases for APIControllerV1
---
 .../fsm/repository/model/GlobalTransaction.java    |   3 +
 .../fsm/repository/model/SagaSubTransaction.java   |   3 +
 .../alpha/server/api/APIControllerV1Tests.java     | 310 +++++++++++++++++++++
 3 files changed, 316 insertions(+)

diff --git a/alpha/alpha-fsm/src/main/java/org/apache/servicecomb/pack/alpha/fsm/repository/model/GlobalTransaction.java b/alpha/alpha-fsm/src/main/java/org/apache/servicecomb/pack/alpha/fsm/repository/model/GlobalTransaction.java
index 8ec31c4..28b4165 100644
--- a/alpha/alpha-fsm/src/main/java/org/apache/servicecomb/pack/alpha/fsm/repository/model/GlobalTransaction.java
+++ b/alpha/alpha-fsm/src/main/java/org/apache/servicecomb/pack/alpha/fsm/repository/model/GlobalTransaction.java
@@ -17,6 +17,7 @@
 
 package org.apache.servicecomb.pack.alpha.fsm.repository.model;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.LinkedList;
@@ -31,7 +32,9 @@ public class GlobalTransaction {
   private TransactionType type;
   private String serviceName;
   private String instanceId;
+  @JsonFormat(shape = JsonFormat.Shape.NUMBER)
   private Date beginTime;
+  @JsonFormat(shape = JsonFormat.Shape.NUMBER)
   private Date endTime;
   private SagaActorState state;
   private Integer subTxSize;
diff --git a/alpha/alpha-fsm/src/main/java/org/apache/servicecomb/pack/alpha/fsm/repository/model/SagaSubTransaction.java b/alpha/alpha-fsm/src/main/java/org/apache/servicecomb/pack/alpha/fsm/repository/model/SagaSubTransaction.java
index a70585e..0c07f35 100644
--- a/alpha/alpha-fsm/src/main/java/org/apache/servicecomb/pack/alpha/fsm/repository/model/SagaSubTransaction.java
+++ b/alpha/alpha-fsm/src/main/java/org/apache/servicecomb/pack/alpha/fsm/repository/model/SagaSubTransaction.java
@@ -17,13 +17,16 @@
 
 package org.apache.servicecomb.pack.alpha.fsm.repository.model;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
 import java.util.Date;
 import org.apache.servicecomb.pack.alpha.fsm.TxState;
 
 public class SagaSubTransaction {
   private String localTxId;
   private String parentTxId;
+  @JsonFormat(shape = JsonFormat.Shape.NUMBER)
   private Date beginTime;
+  @JsonFormat(shape = JsonFormat.Shape.NUMBER)
   private Date endTime;
   private TxState state;
   private Long durationTime;
diff --git a/alpha/alpha-server/src/test/java/org/apache/servicecomb/pack/alpha/server/api/APIControllerV1Tests.java b/alpha/alpha-server/src/test/java/org/apache/servicecomb/pack/alpha/server/api/APIControllerV1Tests.java
new file mode 100644
index 0000000..e4914b2
--- /dev/null
+++ b/alpha/alpha-server/src/test/java/org/apache/servicecomb/pack/alpha/server/api/APIControllerV1Tests.java
@@ -0,0 +1,310 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.servicecomb.pack.alpha.server.api;
+
+import static org.hamcrest.Matchers.hasSize;
+import static org.mockito.Mockito.when;
+import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonGenerator.Feature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.UUID;
+import org.apache.servicecomb.pack.alpha.core.NodeStatus;
+import org.apache.servicecomb.pack.alpha.core.NodeStatus.TypeEnum;
+import org.apache.servicecomb.pack.alpha.fsm.SagaActorState;
+import org.apache.servicecomb.pack.alpha.fsm.TransactionType;
+import org.apache.servicecomb.pack.alpha.fsm.TxState;
+import org.apache.servicecomb.pack.alpha.fsm.event.SagaEndedEvent;
+import org.apache.servicecomb.pack.alpha.fsm.event.SagaStartedEvent;
+import org.apache.servicecomb.pack.alpha.fsm.event.TxEndedEvent;
+import org.apache.servicecomb.pack.alpha.fsm.event.TxStartedEvent;
+import org.apache.servicecomb.pack.alpha.fsm.event.base.BaseEvent;
+import org.apache.servicecomb.pack.alpha.fsm.metrics.MetricsBean;
+import org.apache.servicecomb.pack.alpha.fsm.metrics.MetricsService;
+import org.apache.servicecomb.pack.alpha.fsm.repository.TransactionRepository;
+import org.apache.servicecomb.pack.alpha.fsm.repository.model.GlobalTransaction;
+import org.apache.servicecomb.pack.alpha.fsm.repository.model.PagingGloablTransactions;
+import org.apache.servicecomb.pack.alpha.fsm.repository.model.SagaSubTransaction;
+import org.apache.servicecomb.pack.alpha.server.metrics.AlphaMetrics;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
+
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+
+@RunWith(SpringRunner.class)
+@WebMvcTest(value = {APIControllerV1.class, AlphaMetrics.class})
+public class APIControllerV1Tests {
+
+  @Autowired
+  private MockMvc mockMvc;
+
+  @Autowired
+  AlphaMetrics alphaMetrics;
+
+  @MockBean
+  MetricsService metricsService;
+
+  @MockBean
+  NodeStatus nodeStatus;
+
+  @MockBean
+  ElasticsearchTemplate template;
+
+  @MockBean
+  TransactionRepository transactionRepository;
+
+  @Test
+  public void metricsTest() throws Exception {
+    MetricsBean metricsBean = new MetricsBean();
+    metricsBean.doEventReceived();
+    metricsBean.doEventAccepted();
+    metricsBean.doEventAvgTime(5);
+    metricsBean.doActorReceived();
+    metricsBean.doActorAccepted();
+    metricsBean.doActorAvgTime(5);
+    metricsBean.doRepositoryReceived();
+    metricsBean.doRepositoryAccepted();
+    metricsBean.doRepositoryAvgTime(5);
+    metricsBean.doCommitted();
+    metricsBean.doCompensated();
+    metricsBean.doSuspended();
+    metricsBean.doSagaBeginCounter();
+    metricsBean.doSagaEndCounter();
+    metricsBean.doSagaAvgTime(5);
+    when(metricsService.metrics()).thenReturn(metricsBean);
+    when(nodeStatus.getTypeEnum()).thenReturn(TypeEnum.MASTER);
+    mockMvc.perform(get("/alpha/api/v1/metrics"))
+        .andExpect(status().isOk())
+        .andExpect(
+            MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
+        .andExpect(jsonPath("$.metrics.eventReceived").value(1))
+        .andExpect(jsonPath("$.metrics.eventAccepted").value(1))
+        .andExpect(jsonPath("$.metrics.eventRejected").value(0))
+        .andExpect(jsonPath("$.metrics.eventAvgTime").value(5.0))
+        .andExpect(jsonPath("$.metrics.actorReceived").value(1))
+        .andExpect(jsonPath("$.metrics.actorAccepted").value(1))
+        .andExpect(jsonPath("$.metrics.actorRejected").value(0))
+        .andExpect(jsonPath("$.metrics.actorAvgTime").value(5.0))
+        .andExpect(jsonPath("$.metrics.repositoryReceived").value(1))
+        .andExpect(jsonPath("$.metrics.repositoryAccepted").value(1))
+        .andExpect(jsonPath("$.metrics.repositoryRejected").value(0))
+        .andExpect(jsonPath("$.metrics.repositoryAvgTime").value(5.0))
+        .andExpect(jsonPath("$.metrics.sagaBeginCounter").value(1))
+        .andExpect(jsonPath("$.metrics.sagaEndCounter").value(1))
+        .andExpect(jsonPath("$.metrics.sagaAvgTime").value(5.0))
+        .andExpect(jsonPath("$.metrics.committed").value(1))
+        .andExpect(jsonPath("$.metrics.compensated").value(1))
+        .andExpect(jsonPath("$.metrics.suspended").value(1))
+        .andExpect(jsonPath("$.nodeType").value(TypeEnum.MASTER.name()))
+        .andReturn();
+  }
+
+  @Test
+  public void transactionTest() throws Exception {
+    final String serviceName = "serviceName-1";
+    final String instanceId = "instanceId-1";
+    final String globalTxId = UUID.randomUUID().toString();
+    final String localTxId_1 = UUID.randomUUID().toString();
+    final String localTxId_2 = UUID.randomUUID().toString();
+    final String localTxId_3 = UUID.randomUUID().toString();
+
+    List<BaseEvent> events = new ArrayList();
+    events.add(SagaStartedEvent.builder().serviceName("service_g").instanceId("instance_g")
+        .globalTxId(globalTxId).build());
+    events.add(TxStartedEvent.builder().serviceName("service_c1").instanceId("instance_c1")
+        .globalTxId(globalTxId).parentTxId(globalTxId).localTxId(localTxId_1).build());
+    events.add(TxEndedEvent.builder().serviceName("service_c1").instanceId("instance_c1")
+        .globalTxId(globalTxId).parentTxId(globalTxId).localTxId(localTxId_1).build());
+    events.add(TxStartedEvent.builder().serviceName("service_c2").instanceId("instance_c2")
+        .globalTxId(globalTxId).parentTxId(globalTxId).localTxId(localTxId_2).build());
+    events.add(TxEndedEvent.builder().serviceName("service_c2").instanceId("instance_c2")
+        .globalTxId(globalTxId).parentTxId(globalTxId).localTxId(localTxId_2).build());
+    events.add(TxStartedEvent.builder().serviceName("service_c3").instanceId("instance_c3")
+        .globalTxId(globalTxId).parentTxId(globalTxId).localTxId(localTxId_3).build());
+    events.add(TxEndedEvent.builder().serviceName("service_c3").instanceId("instance_c3")
+        .globalTxId(globalTxId).parentTxId(globalTxId).localTxId(localTxId_3).build());
+    events.add(SagaEndedEvent.builder().serviceName("service_g").instanceId("instance_g")
+        .globalTxId(globalTxId).build());
+
+    List<SagaSubTransaction> subTransactions = new ArrayList();
+    subTransactions
+        .add(SagaSubTransaction.builder().parentTxId(globalTxId).localTxId(localTxId_1).state(
+            TxState.COMMITTED).beginTime(new Date()).endTime(new Date()).build());
+    subTransactions
+        .add(SagaSubTransaction.builder().parentTxId(globalTxId).localTxId(localTxId_2).state(
+            TxState.COMMITTED).beginTime(new Date()).endTime(new Date()).build());
+    subTransactions
+        .add(SagaSubTransaction.builder().parentTxId(globalTxId).localTxId(localTxId_3).state(
+            TxState.COMMITTED).beginTime(new Date()).endTime(new Date()).build());
+
+    List<GlobalTransaction> globalTransactions = new ArrayList<>();
+    globalTransactions.add(GlobalTransaction.builder()
+        .serviceName(serviceName)
+        .instanceId(instanceId)
+        .globalTxId(globalTxId)
+        .type(TransactionType.SAGA)
+        .state(SagaActorState.COMMITTED)
+        .beginTime(new Date())
+        .endTime(new Date())
+        .subTxSize(3)
+        .events(events)
+        .subTransactions(subTransactions)
+        .build());
+    PagingGloablTransactions paging = PagingGloablTransactions.builder()
+        .page(0)
+        .size(50)
+        .elapsed(10)
+        .total(1)
+        .gloablTransactions(globalTransactions)
+        .build();
+
+    when(transactionRepository.getGloablTransactions(0, 50)).thenReturn(paging);
+
+    ObjectMapper mapper = new ObjectMapper();
+    mapper.configure(JsonGenerator.Feature.QUOTE_FIELD_NAMES, false);
+    mapper.configure(Feature.QUOTE_NON_NUMERIC_NUMBERS, false);
+    mockMvc.perform(get("/alpha/api/v1/transaction?page=0&size=50"))
+        .andExpect(status().isOk())
+        .andExpect(
+            MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
+        .andExpect(jsonPath("$.total").value(1))
+        .andExpect(jsonPath("$.page").value(0))
+        .andExpect(jsonPath("$.size").value(50))
+        .andExpect(jsonPath("$.elapsed").value(10))
+        .andExpect(jsonPath("$.globalTransactions", hasSize(1)))
+        .andExpect(jsonPath("$.globalTransactions[0].globalTxId")
+            .value(globalTransactions.get(0).getGlobalTxId()))
+        .andExpect(jsonPath("$.globalTransactions[0].type")
+            .value(globalTransactions.get(0).getType().name()))
+        .andExpect(jsonPath("$.globalTransactions[0].serviceName")
+            .value(globalTransactions.get(0).getServiceName()))
+        .andExpect(jsonPath("$.globalTransactions[0].instanceId")
+            .value(globalTransactions.get(0).getInstanceId()))
+        .andExpect(jsonPath("$.globalTransactions[0].beginTime")
+            .value(globalTransactions.get(0).getBeginTime().getTime()))
+        .andExpect(jsonPath("$.globalTransactions[0].endTime")
+            .value(globalTransactions.get(0).getEndTime().getTime()))
+        .andExpect(jsonPath("$.globalTransactions[0].state")
+            .value(globalTransactions.get(0).getState().name()))
+        .andExpect(jsonPath("$.globalTransactions[0].subTxSize")
+            .value(globalTransactions.get(0).getSubTxSize()))
+        .andExpect(jsonPath("$.globalTransactions[0].durationTime")
+            .value(globalTransactions.get(0).getDurationTime()))
+        .andExpect(jsonPath("$.globalTransactions[0].subTransactions", hasSize(3)))
+        .andExpect(jsonPath("$.globalTransactions[0].events", hasSize(8)))
+        .andReturn();
+  }
+
+  @Test
+  public void globalTransactionByGlobalTxIdTest() throws Exception {
+    final String serviceName = "serviceName-1";
+    final String instanceId = "instanceId-1";
+    final String globalTxId = UUID.randomUUID().toString();
+    final String localTxId_1 = UUID.randomUUID().toString();
+    final String localTxId_2 = UUID.randomUUID().toString();
+    final String localTxId_3 = UUID.randomUUID().toString();
+
+    List<BaseEvent> events = new ArrayList();
+    events.add(SagaStartedEvent.builder().serviceName("service_g").instanceId("instance_g")
+        .globalTxId(globalTxId).build());
+    events.add(TxStartedEvent.builder().serviceName("service_c1").instanceId("instance_c1")
+        .globalTxId(globalTxId).parentTxId(globalTxId).localTxId(localTxId_1).build());
+    events.add(TxEndedEvent.builder().serviceName("service_c1").instanceId("instance_c1")
+        .globalTxId(globalTxId).parentTxId(globalTxId).localTxId(localTxId_1).build());
+    events.add(TxStartedEvent.builder().serviceName("service_c2").instanceId("instance_c2")
+        .globalTxId(globalTxId).parentTxId(globalTxId).localTxId(localTxId_2).build());
+    events.add(TxEndedEvent.builder().serviceName("service_c2").instanceId("instance_c2")
+        .globalTxId(globalTxId).parentTxId(globalTxId).localTxId(localTxId_2).build());
+    events.add(TxStartedEvent.builder().serviceName("service_c3").instanceId("instance_c3")
+        .globalTxId(globalTxId).parentTxId(globalTxId).localTxId(localTxId_3).build());
+    events.add(TxEndedEvent.builder().serviceName("service_c3").instanceId("instance_c3")
+        .globalTxId(globalTxId).parentTxId(globalTxId).localTxId(localTxId_3).build());
+    events.add(SagaEndedEvent.builder().serviceName("service_g").instanceId("instance_g")
+        .globalTxId(globalTxId).build());
+
+    List<SagaSubTransaction> subTransactions = new ArrayList();
+    subTransactions
+        .add(SagaSubTransaction.builder().parentTxId(globalTxId).localTxId(localTxId_1).state(
+            TxState.COMMITTED).beginTime(new Date()).endTime(new Date()).build());
+    subTransactions
+        .add(SagaSubTransaction.builder().parentTxId(globalTxId).localTxId(localTxId_2).state(
+            TxState.COMMITTED).beginTime(new Date()).endTime(new Date()).build());
+    subTransactions
+        .add(SagaSubTransaction.builder().parentTxId(globalTxId).localTxId(localTxId_3).state(
+            TxState.COMMITTED).beginTime(new Date()).endTime(new Date()).build());
+
+    GlobalTransaction globalTransaction = GlobalTransaction.builder()
+        .serviceName(serviceName)
+        .instanceId(instanceId)
+        .globalTxId(globalTxId)
+        .type(TransactionType.SAGA)
+        .state(SagaActorState.COMMITTED)
+        .beginTime(new Date())
+        .endTime(new Date())
+        .subTxSize(3)
+        .events(events)
+        .subTransactions(subTransactions)
+        .build();
+
+    when(transactionRepository.getGloablTransactionByGlobalTxId(globalTxId)).thenReturn(globalTransaction);
+
+    ObjectMapper mapper = new ObjectMapper();
+    mapper.configure(JsonGenerator.Feature.QUOTE_FIELD_NAMES, false);
+    mapper.configure(Feature.QUOTE_NON_NUMERIC_NUMBERS, false);
+    mockMvc.perform(get("/alpha/api/v1/transaction/"+globalTxId))
+        .andDo(print())
+        .andExpect(status().isOk())
+        .andExpect(
+            MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
+        .andExpect(jsonPath("$.globalTxId")
+            .value(globalTransaction.getGlobalTxId()))
+        .andExpect(jsonPath("$.type")
+            .value(globalTransaction.getType().name()))
+        .andExpect(jsonPath("$.serviceName")
+            .value(globalTransaction.getServiceName()))
+        .andExpect(jsonPath("$.instanceId")
+            .value(globalTransaction.getInstanceId()))
+        .andExpect(jsonPath("$.beginTime")
+            .value(globalTransaction.getBeginTime().getTime()))
+        .andExpect(jsonPath("$.endTime")
+            .value(globalTransaction.getEndTime().getTime()))
+        .andExpect(jsonPath("$.state")
+            .value(globalTransaction.getState().name()))
+        .andExpect(jsonPath("$.subTxSize")
+            .value(globalTransaction.getSubTxSize()))
+        .andExpect(jsonPath("$.durationTime")
+            .value(globalTransaction.getDurationTime()))
+        .andExpect(jsonPath("$.subTransactions", hasSize(3)))
+        .andExpect(jsonPath("$.events", hasSize(8)))
+        .andReturn();
+  }
+}