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();
+ }
+}