Repository: alibaba/fescar
Pull request #262 (2019-01-24 03:44:47)

add unit test for server package LockManager and DefaultCore
<!-- Please make sure you have read and understood the contributing guidelines -->

### Ⅰ. Describe what this PR did
add unit test for server package LockManager and DefaultCore

### Ⅱ. Does this pull request fix one issue?
<!-- If that, add "fixes #xxx" below in the next line, for example, fixes #97. -->


### Ⅲ. Why don't you add test cases (unit test/integration test)? 


### Ⅳ. Describe how to verify it


### Ⅴ. Special notes for reviews



slievrly: @xyzhimo review UnitTest case
codecov-io: # [Codecov](https://codecov.io/gh/alibaba/fescar/pull/262?src=pr&el=h1) Report
> Merging [#262](https://codecov.io/gh/alibaba/fescar/pull/262?src=pr&el=desc) into [develop](https://codecov.io/gh/alibaba/fescar/commit/71960a279368f38a950efd07d8385b9fa722b3ae?src=pr&el=desc) will **increase** coverage by `2.24%`.
> The diff coverage is `n/a`.

[![Impacted file tree graph](https://codecov.io/gh/alibaba/fescar/pull/262/graphs/tree.svg?width=650&token=Hy9a6MCc4p&height=150&src=pr)](https://codecov.io/gh/alibaba/fescar/pull/262?src=pr&el=tree)

```diff
@@             Coverage Diff             @@
##           develop     #262      +/-   ##
===========================================
+ Coverage    12.17%   14.41%   +2.24%     
===========================================
  Files          184      184              
  Lines         6828     6828              
  Branches       936      936              
===========================================
+ Hits           831      984     +153     
+ Misses        5918     5737     -181     
- Partials        79      107      +28
```


| [Impacted Files](https://codecov.io/gh/alibaba/fescar/pull/262?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [...m/alibaba/fescar/server/session/BranchSession.java](https://codecov.io/gh/alibaba/fescar/pull/262/diff?src=pr&el=tree#diff-c2VydmVyL3NyYy9tYWluL2phdmEvY29tL2FsaWJhYmEvZmVzY2FyL3NlcnZlci9zZXNzaW9uL0JyYW5jaFNlc3Npb24uamF2YQ==) | `84.55% <0%> (+13.23%)` | :arrow_up: |
| [...m/alibaba/fescar/server/session/GlobalSession.java](https://codecov.io/gh/alibaba/fescar/pull/262/diff?src=pr&el=tree#diff-c2VydmVyL3NyYy9tYWluL2phdmEvY29tL2FsaWJhYmEvZmVzY2FyL3NlcnZlci9zZXNzaW9uL0dsb2JhbFNlc3Npb24uamF2YQ==) | `83.91% <0%> (+19.58%)` | :arrow_up: |
| [...m/alibaba/fescar/server/session/SessionHolder.java](https://codecov.io/gh/alibaba/fescar/pull/262/diff?src=pr&el=tree#diff-c2VydmVyL3NyYy9tYWluL2phdmEvY29tL2FsaWJhYmEvZmVzY2FyL3NlcnZlci9zZXNzaW9uL1Nlc3Npb25Ib2xkZXIuamF2YQ==) | `30.76% <0%> (+30.76%)` | :arrow_up: |
| [...alibaba/fescar/server/coordinator/DefaultCore.java](https://codecov.io/gh/alibaba/fescar/pull/262/diff?src=pr&el=tree#diff-c2VydmVyL3NyYy9tYWluL2phdmEvY29tL2FsaWJhYmEvZmVzY2FyL3NlcnZlci9jb29yZGluYXRvci9EZWZhdWx0Q29yZS5qYXZh) | `31.57% <0%> (+31.57%)` | :arrow_up: |
| [...alibaba/fescar/server/lock/LockManagerFactory.java](https://codecov.io/gh/alibaba/fescar/pull/262/diff?src=pr&el=tree#diff-c2VydmVyL3NyYy9tYWluL2phdmEvY29tL2FsaWJhYmEvZmVzY2FyL3NlcnZlci9sb2NrL0xvY2tNYW5hZ2VyRmFjdG9yeS5qYXZh) | `50% <0%> (+50%)` | :arrow_up: |
| [...aba/fescar/server/lock/DefaultLockManagerImpl.java](https://codecov.io/gh/alibaba/fescar/pull/262/diff?src=pr&el=tree#diff-c2VydmVyL3NyYy9tYWluL2phdmEvY29tL2FsaWJhYmEvZmVzY2FyL3NlcnZlci9sb2NrL0RlZmF1bHRMb2NrTWFuYWdlckltcGwuamF2YQ==) | `65.75% <0%> (+65.75%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/alibaba/fescar/pull/262?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/alibaba/fescar/pull/262?src=pr&el=footer). Last update [71960a2...4190f4f](https://codecov.io/gh/alibaba/fescar/pull/262?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/core/src/main/java/com/alibaba/fescar/core/exception/TransactionExceptionCode.java b/core/src/main/java/com/alibaba/fescar/core/exception/TransactionExceptionCode.java
index ec1cd4bc1..903789edc 100644
--- a/core/src/main/java/com/alibaba/fescar/core/exception/TransactionExceptionCode.java
+++ b/core/src/main/java/com/alibaba/fescar/core/exception/TransactionExceptionCode.java
@@ -69,11 +69,11 @@ public enum TransactionExceptionCode {
 
     ;
 
-    private static final Map<Integer, TransactionExceptionCode> map = new HashMap<>(values().length);
+    private static final Map<Integer, TransactionExceptionCode> MAP = new HashMap<>(values().length);
 
     static {
         for (TransactionExceptionCode code : values()) {
-            map.put(code.ordinal(), code);
+            MAP.put(code.ordinal(), code);
         }
     }
 
@@ -82,7 +82,7 @@ public enum TransactionExceptionCode {
     }
 
     public static TransactionExceptionCode get(int ordinal) {
-        TransactionExceptionCode code = map.get(ordinal);
+        TransactionExceptionCode code = MAP.get(ordinal);
 
         if (null == code) {
             throw new IllegalArgumentException("Unknown TransactionExceptionCode[" + ordinal + "]");
diff --git a/core/src/main/java/com/alibaba/fescar/core/model/BranchStatus.java b/core/src/main/java/com/alibaba/fescar/core/model/BranchStatus.java
index c6774651b..d72a2e802 100644
--- a/core/src/main/java/com/alibaba/fescar/core/model/BranchStatus.java
+++ b/core/src/main/java/com/alibaba/fescar/core/model/BranchStatus.java
@@ -59,11 +59,11 @@ public enum BranchStatus {
     // Rollback logic is failed but NOT retryable.
     PhaseTwo_RollbackFailed_Unretryable;
 
-    private static final Map<Integer, BranchStatus> map = new HashMap<>(values().length);
+    private static final Map<Integer, BranchStatus> MAP = new HashMap<>(values().length);
 
     static {
         for (BranchStatus status : values()) {
-            map.put(status.ordinal(), status);
+            MAP.put(status.ordinal(), status);
         }
     }
 
@@ -72,7 +72,7 @@ public enum BranchStatus {
     }
 
     public static BranchStatus get(int ordinal) {
-        BranchStatus status = map.get(ordinal);
+        BranchStatus status = MAP.get(ordinal);
 
         if (null == status) {
             throw new ShouldNeverHappenException("Unknown BranchStatus[" + ordinal + "]");
diff --git a/core/src/main/java/com/alibaba/fescar/core/model/GlobalStatus.java b/core/src/main/java/com/alibaba/fescar/core/model/GlobalStatus.java
index 95cca7f20..ef9b3ba33 100644
--- a/core/src/main/java/com/alibaba/fescar/core/model/GlobalStatus.java
+++ b/core/src/main/java/com/alibaba/fescar/core/model/GlobalStatus.java
@@ -72,14 +72,14 @@ public enum GlobalStatus {
     // Finally: failed to rollback since timeout
     TimeoutRollbackFailed,
 
-    // Not managed in session map any more
+    // Not managed in session MAP any more
     Finished;
 
-    private static final Map<Integer, GlobalStatus> map = new HashMap<>(values().length);
+    private static final Map<Integer, GlobalStatus> MAP = new HashMap<>(values().length);
 
     static {
         for (GlobalStatus status : values()) {
-            map.put(status.ordinal(), status);
+            MAP.put(status.ordinal(), status);
         }
     }
 
@@ -88,7 +88,7 @@ public enum GlobalStatus {
     }
 
     public static GlobalStatus get(int ordinal) {
-        GlobalStatus status = map.get(ordinal);
+        GlobalStatus status = MAP.get(ordinal);
 
         if (null == status) {
             throw new IllegalArgumentException("Unknown GlobalStatus[" + ordinal + "]");
diff --git a/core/src/main/java/com/alibaba/fescar/core/protocol/transaction/AbstractGlobalEndRequest.java b/core/src/main/java/com/alibaba/fescar/core/protocol/transaction/AbstractGlobalEndRequest.java
index be008e279..b41b4a00a 100644
--- a/core/src/main/java/com/alibaba/fescar/core/protocol/transaction/AbstractGlobalEndRequest.java
+++ b/core/src/main/java/com/alibaba/fescar/core/protocol/transaction/AbstractGlobalEndRequest.java
@@ -16,10 +16,10 @@
 
 package com.alibaba.fescar.core.protocol.transaction;
 
-import java.nio.ByteBuffer;
-
 import com.alibaba.fescar.core.protocol.MergedMessage;
 
+import java.nio.ByteBuffer;
+
 public abstract class AbstractGlobalEndRequest extends AbstractTransactionRequestToTC implements MergedMessage {
 
     protected long transactionId;
@@ -72,4 +72,16 @@ public abstract class AbstractGlobalEndRequest extends AbstractTransactionReques
             this.setExtraData(new String(bs, UTF8));
         }
     }
+
+    @Override
+    public String toString() {
+        StringBuilder result = new StringBuilder();
+        result.append("transactionId=");
+        result.append(transactionId);
+        result.append(",");
+        result.append("extraData=");
+        result.append(extraData);
+
+        return result.toString();
+    }
 }
diff --git a/core/src/main/java/com/alibaba/fescar/core/protocol/transaction/AbstractGlobalEndResponse.java b/core/src/main/java/com/alibaba/fescar/core/protocol/transaction/AbstractGlobalEndResponse.java
index 28767a384..2e94e380e 100644
--- a/core/src/main/java/com/alibaba/fescar/core/protocol/transaction/AbstractGlobalEndResponse.java
+++ b/core/src/main/java/com/alibaba/fescar/core/protocol/transaction/AbstractGlobalEndResponse.java
@@ -16,10 +16,10 @@
 
 package com.alibaba.fescar.core.protocol.transaction;
 
-import java.nio.ByteBuffer;
-
 import com.alibaba.fescar.core.model.GlobalStatus;
 
+import java.nio.ByteBuffer;
+
 public abstract class AbstractGlobalEndResponse extends AbstractTransactionResponse {
 
     protected GlobalStatus globalStatus;
@@ -45,4 +45,18 @@ public abstract class AbstractGlobalEndResponse extends AbstractTransactionRespo
         globalStatus = GlobalStatus.get(byteBuffer.get());
     }
 
+    @Override
+    public String toString() {
+        StringBuilder result = new StringBuilder();
+        result.append("globalStatus=");
+        result.append(globalStatus);
+        result.append(",");
+        result.append("ResultCode=");
+        result.append(getResultCode());
+        result.append(",");
+        result.append("Msg=");
+        result.append(getMsg());
+
+        return result.toString();
+    }
 }
diff --git a/core/src/main/java/com/alibaba/fescar/core/protocol/transaction/BranchReportRequest.java b/core/src/main/java/com/alibaba/fescar/core/protocol/transaction/BranchReportRequest.java
index 4fdc53cc3..896028554 100644
--- a/core/src/main/java/com/alibaba/fescar/core/protocol/transaction/BranchReportRequest.java
+++ b/core/src/main/java/com/alibaba/fescar/core/protocol/transaction/BranchReportRequest.java
@@ -16,12 +16,12 @@
 
 package com.alibaba.fescar.core.protocol.transaction;
 
-import java.nio.ByteBuffer;
-
 import com.alibaba.fescar.core.model.BranchStatus;
 import com.alibaba.fescar.core.protocol.MergedMessage;
 import com.alibaba.fescar.core.rpc.RpcContext;
 
+import java.nio.ByteBuffer;
+
 public class BranchReportRequest extends AbstractTransactionRequestToTC implements MergedMessage {
 
     private long transactionId;
@@ -146,4 +146,25 @@ public class BranchReportRequest extends AbstractTransactionRequestToTC implemen
     public AbstractTransactionResponse handle(RpcContext rpcContext) {
         return handler.handle(this, rpcContext);
     }
+
+    @Override
+    public String toString() {
+        StringBuilder result = new StringBuilder();
+        result.append("transactionId=");
+        result.append(transactionId);
+        result.append(",");
+        result.append("branchId=");
+        result.append(branchId);
+        result.append(",");
+        result.append("resourceId=");
+        result.append(resourceId);
+        result.append(",");
+        result.append("status=");
+        result.append(status);
+        result.append(",");
+        result.append("applicationData=");
+        result.append(applicationData);
+
+        return result.toString();
+    }
 }
diff --git a/core/src/main/java/com/alibaba/fescar/core/protocol/transaction/GlobalBeginRequest.java b/core/src/main/java/com/alibaba/fescar/core/protocol/transaction/GlobalBeginRequest.java
index c6f4d6faa..af589f9bd 100644
--- a/core/src/main/java/com/alibaba/fescar/core/protocol/transaction/GlobalBeginRequest.java
+++ b/core/src/main/java/com/alibaba/fescar/core/protocol/transaction/GlobalBeginRequest.java
@@ -16,11 +16,11 @@
 
 package com.alibaba.fescar.core.protocol.transaction;
 
-import java.nio.ByteBuffer;
-
 import com.alibaba.fescar.core.protocol.MergedMessage;
 import com.alibaba.fescar.core.rpc.RpcContext;
 
+import java.nio.ByteBuffer;
+
 public class GlobalBeginRequest extends AbstractTransactionRequestToTC implements MergedMessage {
 
     private static final long serialVersionUID = 7236162274218388376L;
@@ -87,4 +87,16 @@ public class GlobalBeginRequest extends AbstractTransactionRequestToTC implement
     public AbstractTransactionResponse handle(RpcContext rpcContext) {
         return handler.handle(this, rpcContext);
     }
+
+    @Override
+    public String toString() {
+        StringBuilder result = new StringBuilder();
+        result.append("timeout=");
+        result.append(timeout);
+        result.append(",");
+        result.append("transactionName=");
+        result.append(transactionName);
+
+        return result.toString();
+    }
 }
diff --git a/core/src/main/java/com/alibaba/fescar/core/rpc/DefaultServerMessageListenerImpl.java b/core/src/main/java/com/alibaba/fescar/core/rpc/DefaultServerMessageListenerImpl.java
index 58a8917a9..fad9500f7 100644
--- a/core/src/main/java/com/alibaba/fescar/core/rpc/DefaultServerMessageListenerImpl.java
+++ b/core/src/main/java/com/alibaba/fescar/core/rpc/DefaultServerMessageListenerImpl.java
@@ -94,8 +94,7 @@ public class DefaultServerMessageListenerImpl implements ServerMessageListener {
 
         boolean isSuccess = false;
         try {
-            if (null == checkAuthHandler || null != checkAuthHandler && checkAuthHandler.regResourceManagerCheckAuth(
-                message)) {
+            if (null == checkAuthHandler || checkAuthHandler.regResourceManagerCheckAuth(message)) {
                 ChannelManager.registerRMChannel(message, ctx.channel());
                 Version.putChannelVersion(ctx.channel(), message.getVersion());
                 isSuccess = true;
@@ -117,8 +116,7 @@ public class DefaultServerMessageListenerImpl implements ServerMessageListener {
         Version.putChannelVersion(ctx.channel(), message.getVersion());
         boolean isSuccess = false;
         try {
-            if (null == checkAuthHandler || null != checkAuthHandler && checkAuthHandler.regTransactionManagerCheckAuth(
-                message)) {
+            if (null == checkAuthHandler || checkAuthHandler.regTransactionManagerCheckAuth(message)) {
                 ChannelManager.registerTMChannel(message, ctx.channel());
                 Version.putChannelVersion(ctx.channel(), message.getVersion());
                 isSuccess = true;
diff --git a/server/src/main/java/com/alibaba/fescar/server/coordinator/DefaultCore.java b/server/src/main/java/com/alibaba/fescar/server/coordinator/DefaultCore.java
index 7b6fb8add..005797884 100644
--- a/server/src/main/java/com/alibaba/fescar/server/coordinator/DefaultCore.java
+++ b/server/src/main/java/com/alibaba/fescar/server/coordinator/DefaultCore.java
@@ -265,12 +265,7 @@ public class DefaultCore implements Core {
                         LOGGER.error("Successfully rolled back branch " + branchSession);
                         continue;
                     case PhaseTwo_RollbackFailed_Unretryable:
-                        GlobalStatus currentStatus = globalSession.getStatus();
-                        if (currentStatus.name().startsWith("Timeout")) {
-                            globalSession.changeStatus(GlobalStatus.TimeoutRollbackFailed);
-                        } else {
-                            globalSession.changeStatus(GlobalStatus.RollbackFailed);
-                        }
+                        changeToRollbackFailedStatus(globalSession);
                         globalSession.end();
                         LOGGER.error("Failed to rollback global[" + globalSession.getTransactionId() + "] since branch[" + branchSession.getBranchId() + "] rollback failed");
                         return;
@@ -296,13 +291,30 @@ public class DefaultCore implements Core {
             }
 
         }
+        if (globalSession.hasBranch()) {
+            changeToRollbackFailedStatus(globalSession);
+        } else {
+            changeToRollbackedStatus(globalSession);
+        }
+        globalSession.end();
+    }
+
+    private void changeToRollbackedStatus(GlobalSession globalSession) throws TransactionException {
         GlobalStatus currentStatus = globalSession.getStatus();
         if (currentStatus.name().startsWith("Timeout")) {
             globalSession.changeStatus(GlobalStatus.TimeoutRollbacked);
         } else {
             globalSession.changeStatus(GlobalStatus.Rollbacked);
         }
-        globalSession.end();
+    }
+
+    private void changeToRollbackFailedStatus(GlobalSession globalSession) throws TransactionException {
+        GlobalStatus currentStatus = globalSession.getStatus();
+        if (currentStatus.name().startsWith("Timeout")) {
+            globalSession.changeStatus(GlobalStatus.TimeoutRollbackFailed);
+        } else {
+            globalSession.changeStatus(GlobalStatus.RollbackFailed);
+        }
     }
 
     @Override
diff --git a/spring/pom.xml b/spring/pom.xml
index 7140c055b..cd6808f99 100644
--- a/spring/pom.xml
+++ b/spring/pom.xml
@@ -44,11 +44,6 @@
             <artifactId>spring</artifactId>
             <scope>provided</scope>
         </dependency>
-        <dependency>
-            <groupId>org.springframework</groupId>
-            <artifactId>spring</artifactId>
-            <scope>provided</scope>
-        </dependency>
         <dependency>
             <groupId>cglib</groupId>
             <artifactId>cglib</artifactId>


Test patch:
diff --git a/core/src/test/java/com/alibaba/fescar/core/message/BranchReportRequestTest.java b/core/src/test/java/com/alibaba/fescar/core/message/BranchReportRequestTest.java
new file mode 100644
index 000000000..ccc6b0422
--- /dev/null
+++ b/core/src/test/java/com/alibaba/fescar/core/message/BranchReportRequestTest.java
@@ -0,0 +1,92 @@
+/*
+ *  Copyright 1999-2018 Alibaba Group Holding Ltd.
+ *
+ *  Licensed 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 com.alibaba.fescar.core.message;
+
+import com.alibaba.fescar.core.model.BranchStatus;
+import com.alibaba.fescar.core.protocol.transaction.BranchReportRequest;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+/**
+ * @author xiajun.0706@163.com
+ * @since 2019/1/24
+ */
+public class BranchReportRequestTest {
+
+  @Test
+  public void testToString() throws Exception {
+    BranchReportRequest branchReportRequest = new BranchReportRequest();
+
+    branchReportRequest.setTransactionId(1249853);
+    branchReportRequest.setBranchId(3);
+    branchReportRequest.setResourceId("resource003");
+    branchReportRequest.setStatus(BranchStatus.PhaseOne_Timeout);
+    branchReportRequest.setApplicationData("test app data");
+
+    Assert.assertEquals("transactionId=1249853,branchId=3,resourceId=resource003,status=PhaseOne_Timeout,applicationData=test app data",
+                        branchReportRequest.toString());
+  }
+
+
+  @Test
+  public void testEncode() throws Exception{
+    BranchReportRequest branchReportRequest = new BranchReportRequest();
+
+    branchReportRequest.setTransactionId(1249853);
+    branchReportRequest.setBranchId(3);
+    branchReportRequest.setResourceId("resource003");
+    branchReportRequest.setStatus(BranchStatus.PhaseOne_Timeout);
+    branchReportRequest.setApplicationData("test app data");
+
+    byte[] encodeResult = branchReportRequest.encode();
+    System.out.println(encodeResult);
+    String encodeResultStr = Arrays.toString(encodeResult);
+    System.out.println(encodeResultStr);
+
+
+    Assert.assertEquals("[0, 0, 0, 0, 0, 19, 18, 61, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 11, 114, 101, 115, 111, 117, 114, 99, 101, 48, 48, 51, 0, 0, 0, 13, 116, 101, 115, 116, 32, 97, 112, 112, 32, 100, 97, 116, 97]", encodeResultStr);
+  }
+
+  @Test
+  public void testDecode() throws Exception{
+    BranchReportRequest branchReportRequest = new BranchReportRequest();
+
+    branchReportRequest.setTransactionId(1249853);
+    branchReportRequest.setBranchId(3);
+    branchReportRequest.setResourceId("resource003");
+    branchReportRequest.setStatus(BranchStatus.PhaseOne_Timeout);
+    branchReportRequest.setApplicationData("test app data");
+
+    byte[] encodeResult = branchReportRequest.encode();
+
+    ByteBuffer byteBuffer = ByteBuffer.allocate(encodeResult.length);
+    byteBuffer.put(encodeResult);
+    byteBuffer.flip();
+
+    BranchReportRequest decodeBranchReportRequest = new BranchReportRequest();
+    decodeBranchReportRequest.decode(byteBuffer);
+    System.out.println(decodeBranchReportRequest);
+    Assert.assertEquals(branchReportRequest.getTransactionId(), decodeBranchReportRequest.getTransactionId());
+    Assert.assertEquals(branchReportRequest.getBranchId(), decodeBranchReportRequest.getBranchId());
+    Assert.assertEquals(branchReportRequest.getResourceId(), decodeBranchReportRequest.getResourceId());
+    Assert.assertEquals(branchReportRequest.getStatus(), decodeBranchReportRequest.getStatus());
+    Assert.assertEquals(branchReportRequest.getApplicationData(), decodeBranchReportRequest.getApplicationData());
+  }
+}
\ No newline at end of file
diff --git a/core/src/test/java/com/alibaba/fescar/core/message/GlobalBeginRequestTest.java b/core/src/test/java/com/alibaba/fescar/core/message/GlobalBeginRequestTest.java
new file mode 100644
index 000000000..0d6ec9ed1
--- /dev/null
+++ b/core/src/test/java/com/alibaba/fescar/core/message/GlobalBeginRequestTest.java
@@ -0,0 +1,69 @@
+/*
+ *  Copyright 1999-2018 Alibaba Group Holding Ltd.
+ *
+ *  Licensed 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 com.alibaba.fescar.core.message;
+
+import com.alibaba.fescar.core.protocol.transaction.GlobalBeginRequest;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+/**
+ * @author xiajun.0706@163.com
+ * @since 2019/1/24
+ */
+public class GlobalBeginRequestTest {
+
+  @Test
+  public void testToString() throws Exception{
+    GlobalBeginRequest globalBeginRequest = new GlobalBeginRequest();
+    globalBeginRequest.setTransactionName("tran 1");
+    System.out.println(globalBeginRequest.toString());
+
+    Assert.assertEquals("timeout=60000,transactionName=tran 1", globalBeginRequest.toString());
+  }
+
+  @Test
+  public void testEncode() throws Exception{
+    GlobalBeginRequest globalBeginRequest = new GlobalBeginRequest();
+    globalBeginRequest.setTransactionName("tran 1");
+
+    byte[] encodeResult = globalBeginRequest.encode();
+    String encodeResultStr = Arrays.toString(encodeResult);
+
+    Assert.assertEquals("[0, 0, -22, 96, 0, 6, 116, 114, 97, 110, 32, 49]", encodeResultStr);
+  }
+
+  @Test
+  public void testDecode() throws Exception{
+    GlobalBeginRequest globalBeginRequest = new GlobalBeginRequest();
+    globalBeginRequest.setTransactionName("tran 1");
+
+    byte[] encodeResult = globalBeginRequest.encode();
+
+    ByteBuffer byteBuffer = ByteBuffer.allocate(encodeResult.length);
+    byteBuffer.put(encodeResult);
+    byteBuffer.flip();
+
+    GlobalBeginRequest decodeGlobalBeginRequest = new GlobalBeginRequest();
+    decodeGlobalBeginRequest.decode(byteBuffer);
+    System.out.println(decodeGlobalBeginRequest);
+    Assert.assertEquals(globalBeginRequest.getTimeout(), decodeGlobalBeginRequest.getTimeout());
+    Assert.assertEquals(globalBeginRequest.getTransactionName(), decodeGlobalBeginRequest.getTransactionName());
+  }
+}
\ No newline at end of file
diff --git a/core/src/test/java/com/alibaba/fescar/core/message/GlobalCommitResponseTest.java b/core/src/test/java/com/alibaba/fescar/core/message/GlobalCommitResponseTest.java
new file mode 100644
index 000000000..c0d2bc22f
--- /dev/null
+++ b/core/src/test/java/com/alibaba/fescar/core/message/GlobalCommitResponseTest.java
@@ -0,0 +1,117 @@
+/*
+ *  Copyright 1999-2018 Alibaba Group Holding Ltd.
+ *
+ *  Licensed 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 com.alibaba.fescar.core.message;
+
+import com.alibaba.fescar.core.model.GlobalStatus;
+import com.alibaba.fescar.core.protocol.ResultCode;
+import com.alibaba.fescar.core.protocol.transaction.GlobalCommitResponse;
+
+import org.apache.commons.lang.StringUtils;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+/**
+ * @author xiajun.0706@163.com
+ * @since 2019/1/24
+ */
+public class GlobalCommitResponseTest {
+
+  @Test
+  public void testToString() throws Exception{
+    GlobalCommitResponse globalCommitResponse = new GlobalCommitResponse();
+
+    globalCommitResponse.setGlobalStatus(GlobalStatus.Committed);
+    globalCommitResponse.setResultCode(ResultCode.Success);
+    globalCommitResponse.setMsg("OK");
+
+    System.out.println(globalCommitResponse.toString());
+
+    Assert.assertEquals("globalStatus=Committed,ResultCode=Success,Msg=OK", globalCommitResponse.toString());
+  }
+
+  @Test
+  public void testEncode() throws Exception{
+    GlobalCommitResponse globalCommitResponse = new GlobalCommitResponse();
+
+    globalCommitResponse.setGlobalStatus(GlobalStatus.Committed);
+    globalCommitResponse.setResultCode(ResultCode.Success);
+    globalCommitResponse.setMsg("OK");
+
+    System.out.println(globalCommitResponse.toString());
+
+    byte[] encodeResult = globalCommitResponse.encode();
+    System.out.println(encodeResult);
+    String encodeResultStr = Arrays.toString(encodeResult);
+    System.out.println(encodeResultStr);
+
+
+    Assert.assertEquals("[1, 0, 8]", encodeResultStr);
+  }
+
+  @Test
+  public void testDecodeNormal() throws Exception{
+    GlobalCommitResponse globalCommitResponse = new GlobalCommitResponse();
+
+    globalCommitResponse.setGlobalStatus(GlobalStatus.Committed);
+    globalCommitResponse.setResultCode(ResultCode.Success);
+    globalCommitResponse.setMsg("OK");
+
+    System.out.println(globalCommitResponse.toString());
+
+    byte[] encodeResult = globalCommitResponse.encode();
+
+    ByteBuffer byteBuffer = ByteBuffer.allocate(encodeResult.length);
+    byteBuffer.put(encodeResult);
+    byteBuffer.flip();
+    GlobalCommitResponse decodeGlobalCommitResponse = new GlobalCommitResponse();
+    decodeGlobalCommitResponse.decode(byteBuffer);
+
+    System.out.println(decodeGlobalCommitResponse.toString());
+
+    Assert.assertEquals(globalCommitResponse.getGlobalStatus(), decodeGlobalCommitResponse.getGlobalStatus());
+    Assert.assertEquals(globalCommitResponse.getResultCode(), decodeGlobalCommitResponse.getResultCode());
+    //success response do not have msg
+    Assert.assertTrue(StringUtils.isBlank(decodeGlobalCommitResponse.getMsg()));
+  }
+
+  @Test
+  public void testDecodeException() throws Exception{
+    GlobalCommitResponse globalCommitResponse = new GlobalCommitResponse();
+
+    globalCommitResponse.setGlobalStatus(GlobalStatus.CommitFailed);
+    globalCommitResponse.setResultCode(ResultCode.Failed);
+    globalCommitResponse.setMsg("error happened");
+
+    System.out.println(globalCommitResponse.toString());
+
+    byte[] encodeResult = globalCommitResponse.encode();
+
+    ByteBuffer byteBuffer = ByteBuffer.allocate(encodeResult.length);
+    byteBuffer.put(encodeResult);
+    byteBuffer.flip();
+    GlobalCommitResponse decodeGlobalCommitResponse = new GlobalCommitResponse();
+    decodeGlobalCommitResponse.decode(byteBuffer);
+
+    System.out.println(decodeGlobalCommitResponse.toString());
+
+    Assert.assertEquals(globalCommitResponse.getGlobalStatus(), decodeGlobalCommitResponse.getGlobalStatus());
+    Assert.assertEquals(globalCommitResponse.getResultCode(), decodeGlobalCommitResponse.getResultCode());
+    Assert.assertEquals(globalCommitResponse.getMsg(), decodeGlobalCommitResponse.getMsg());
+  }
+}
\ No newline at end of file
diff --git a/core/src/test/java/com/alibaba/fescar/core/message/GlobalRollbackRequestTest.java b/core/src/test/java/com/alibaba/fescar/core/message/GlobalRollbackRequestTest.java
new file mode 100644
index 000000000..23217ee02
--- /dev/null
+++ b/core/src/test/java/com/alibaba/fescar/core/message/GlobalRollbackRequestTest.java
@@ -0,0 +1,81 @@
+/*
+ *  Copyright 1999-2018 Alibaba Group Holding Ltd.
+ *
+ *  Licensed 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 com.alibaba.fescar.core.message;
+
+import com.alibaba.fescar.core.protocol.transaction.GlobalRollbackRequest;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+/**
+ * @author xiajun.0706@163.com
+ * @since 2019/1/24
+ */
+public class GlobalRollbackRequestTest {
+
+  @Test
+  public void testToString() throws Exception{
+    GlobalRollbackRequest globalRollbackRequest = new GlobalRollbackRequest();
+
+    globalRollbackRequest.setTransactionId(1249853);
+    globalRollbackRequest.setExtraData("test_extra_data");
+
+    System.out.println(globalRollbackRequest.toString());
+
+    Assert.assertEquals("transactionId=1249853,extraData=test_extra_data", globalRollbackRequest.toString());
+  }
+
+  @Test
+  public void testEncode() throws Exception{
+    GlobalRollbackRequest globalRollbackRequest = new GlobalRollbackRequest();
+
+    globalRollbackRequest.setTransactionId(1249853);
+    globalRollbackRequest.setExtraData("test_extra_data");
+
+    System.out.println(globalRollbackRequest.toString());
+
+    byte[] encodeResult = globalRollbackRequest.encode();
+    System.out.println(encodeResult);
+    String encodeResultStr = Arrays.toString(encodeResult);
+    System.out.println(encodeResultStr);
+
+
+    Assert.assertEquals("[0, 0, 0, 0, 0, 19, 18, 61, 0, 15, 116, 101, 115, 116, 95, 101, 120, 116, 114, 97, 95, 100, 97, 116, 97]", encodeResultStr);
+  }
+
+  @Test
+  public void testDecode() throws Exception{
+    GlobalRollbackRequest globalRollbackRequest = new GlobalRollbackRequest();
+
+    globalRollbackRequest.setTransactionId(1249853L);
+    globalRollbackRequest.setExtraData("test_extra_data");
+
+    byte[] encodeResult = globalRollbackRequest.encode();
+
+    ByteBuffer byteBuffer = ByteBuffer.allocate(encodeResult.length);
+    byteBuffer.put(encodeResult);
+    byteBuffer.flip();
+
+    GlobalRollbackRequest decodeGlobalRollbackRequest = new GlobalRollbackRequest();
+    decodeGlobalRollbackRequest.decode(byteBuffer);
+    System.out.println(decodeGlobalRollbackRequest);
+    Assert.assertEquals(globalRollbackRequest.getTransactionId(), decodeGlobalRollbackRequest.getTransactionId());
+    Assert.assertEquals(globalRollbackRequest.getExtraData(), decodeGlobalRollbackRequest.getExtraData());
+  }
+}
\ No newline at end of file
diff --git a/server/src/test/java/com/alibaba/fescar/server/coordinator/DefaultCoreTest.java b/server/src/test/java/com/alibaba/fescar/server/coordinator/DefaultCoreTest.java
new file mode 100644
index 000000000..407454917
--- /dev/null
+++ b/server/src/test/java/com/alibaba/fescar/server/coordinator/DefaultCoreTest.java
@@ -0,0 +1,141 @@
+/*
+ *  Copyright 1999-2018 Alibaba Group Holding Ltd.
+ *
+ *  Licensed 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 com.alibaba.fescar.server.coordinator;
+
+import com.alibaba.fescar.common.XID;
+import com.alibaba.fescar.core.model.BranchStatus;
+import com.alibaba.fescar.core.model.BranchType;
+import com.alibaba.fescar.core.model.GlobalStatus;
+import com.alibaba.fescar.server.session.BranchSession;
+import com.alibaba.fescar.server.session.GlobalSession;
+import com.alibaba.fescar.server.session.SessionHolder;
+import org.testng.Assert;
+import org.testng.annotations.*;
+
+import java.util.Collection;
+
+/**
+ * @author zhimo.xiao@gmail.com
+ * @since 2019/1/23
+ */
+
+public class DefaultCoreTest {
+
+    private static Core core = new DefaultCore();
+
+    private static final String applicationId = "demo-child-app";
+
+    private static final String txServiceGroup = "my_test_tx_group";
+
+    private static final String txName = "tx-1";
+
+    private static final int timeout = 3000;
+
+    private static final String resourceId = "tb_1";
+
+    private static final String clientId = "c_1";
+
+    private static final String lockKeys_1 = "tb_1:11";
+
+    private static final String lockKeys_2 = "tb_1:12";
+
+    private static final String applicationData = "{\"data\":\"test\"}";
+
+    @BeforeTest
+    public void initSessionManager() throws Exception {
+        SessionHolder.init(null);
+    }
+
+    @Test(dataProvider = "xidProvider")
+    public void branchRegisterTest(String xid) throws Exception {
+        core.branchRegister(BranchType.AT, resourceId, clientId, xid, lockKeys_1);
+
+        long transactionId = XID.getTransactionId(xid);
+        GlobalSession globalSession = SessionHolder.findGlobalSession(transactionId);
+        Assert.assertEquals(globalSession.getSortedBranches().size(), 1);
+    }
+
+    @Test(dataProvider = "xidAndBranchIdProvider")
+    public void branchReportTest(String xid, Long branchId) throws Exception {
+        core.branchReport(xid, branchId, BranchStatus.PhaseOne_Done, applicationData);
+
+        long transactionId = XID.getTransactionId(xid);
+        GlobalSession globalSession = SessionHolder.findGlobalSession(transactionId);
+        BranchSession branchSession = globalSession.getBranch(branchId);
+        Assert.assertEquals(branchSession.getStatus(), BranchStatus.PhaseOne_Done);
+    }
+
+    @Test
+    public void beginTest() throws Exception {
+        String xid = core.begin(applicationId, txServiceGroup, txName, timeout);
+
+        long transactionId = XID.getTransactionId(xid);
+        GlobalSession globalSession = SessionHolder.findGlobalSession(transactionId);
+        Assert.assertNotNull(globalSession);
+    }
+
+    @Test(dataProvider = "xidProvider")
+    public void commitTest(String xid) throws Exception {
+        GlobalStatus globalStatus = core.commit(xid);
+        Assert.assertEquals(globalStatus, GlobalStatus.Begin);
+    }
+
+    @Test(dataProvider = "xidProvider")
+    public void doGlobalCommitTest(String xid) throws Exception {
+        GlobalSession globalSession = SessionHolder.findGlobalSession(XID.getTransactionId(xid));
+        core.doGlobalCommit(globalSession, false);
+        Assert.assertEquals(globalSession.getStatus(), GlobalStatus.Committed);
+    }
+
+    @Test(dataProvider = "xidProvider")
+    public void rollBackTest(String xid) throws Exception {
+        GlobalStatus globalStatus = core.rollback(xid);
+        Assert.assertEquals(globalStatus, GlobalStatus.Rollbacked);
+    }
+
+    @Test(dataProvider = "xidProvider")
+    public void doGlobalRollBackTest(String xid) throws Exception {
+        GlobalSession globalSession = SessionHolder.findGlobalSession(XID.getTransactionId(xid));
+        core.doGlobalRollback(globalSession, false);
+        Assert.assertEquals(globalSession.getStatus(), GlobalStatus.Rollbacked);
+    }
+
+    @DataProvider
+    public static Object[][] xidProvider() throws Exception {
+        String xid = core.begin(applicationId, txServiceGroup, txName, timeout);
+        return new Object[][]{{xid}};
+    }
+
+    @DataProvider
+    public static Object[][] xidAndBranchIdProvider() throws Exception {
+        String xid = core.begin(applicationId, txServiceGroup, txName, timeout);
+        Long branchId = core.branchRegister(BranchType.AT, resourceId, clientId, xid, lockKeys_2);
+        return new Object[][]{{xid, branchId}};
+    }
+
+    @AfterTest
+    public void releaseSessionManager() throws Exception {
+        Collection<GlobalSession> globalSessions = SessionHolder.getRootSessionManager().allSessions();
+        Collection<GlobalSession> asyncGlobalSessions = SessionHolder.getAsyncCommittingSessionManager().allSessions();
+        for (GlobalSession asyncGlobalSession : asyncGlobalSessions) {
+            asyncGlobalSession.closeAndClean();
+        }
+        for (GlobalSession globalSession : globalSessions) {
+            globalSession.closeAndClean();
+        }
+    }
+
+}
diff --git a/server/src/test/java/com/alibaba/fescar/server/lock/DefaultLockManagerImplTest.java b/server/src/test/java/com/alibaba/fescar/server/lock/DefaultLockManagerImplTest.java
new file mode 100644
index 000000000..64696266c
--- /dev/null
+++ b/server/src/test/java/com/alibaba/fescar/server/lock/DefaultLockManagerImplTest.java
@@ -0,0 +1,70 @@
+/*
+ *  Copyright 1999-2018 Alibaba Group Holding Ltd.
+ *
+ *  Licensed 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 com.alibaba.fescar.server.lock;
+
+import com.alibaba.fescar.core.model.BranchType;
+import com.alibaba.fescar.server.UUIDGenerator;
+import com.alibaba.fescar.server.session.BranchSession;
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+/**
+ * @author zhimo.xiao@gmail.com
+ * @since 2019/1/23
+ */
+
+public class DefaultLockManagerImplTest {
+
+    private LockManager lockManager = new DefaultLockManagerImpl();
+
+    private static final long transactionId = UUIDGenerator.generateUUID();
+
+    private static final String resourceId = "tb_1";
+
+    private static final String lockKey = "tb_1:13";
+
+    @Test(dataProvider = "branchSessionProvider")
+    public void acquireLockTest(BranchSession branchSession) throws Exception {
+        boolean result = lockManager.acquireLock(branchSession);
+        Assert.assertTrue(result);
+        branchSession.unlock();
+    }
+
+    @Test
+    public void isLockableTest() throws Exception {
+        boolean resultOne = lockManager.isLockable(transactionId, resourceId, lockKey);
+        Assert.assertTrue(resultOne);
+    }
+
+    @DataProvider
+    public static Object[][] branchSessionProvider() {
+        BranchSession branchSession = new BranchSession();
+        branchSession.setBranchId(1L);
+        branchSession.setTransactionId(transactionId);
+        branchSession.setClientId("c1");
+        branchSession.setResourceGroupId("my_test_tx_group");
+        branchSession.setResourceId(resourceId);
+        branchSession.setLockKey(lockKey);
+        branchSession.setBranchType(BranchType.AT);
+        branchSession.setApplicationId("demo-child-app");
+        branchSession.setTxServiceGroup("my_test_tx_group");
+        branchSession.setApplicationData("{\"data\":\"test\"}");
+        branchSession.setBranchType(BranchType.AT);
+        return new Object[][]{{branchSession}};
+    }
+
+}
diff --git a/server/src/test/java/com/alibaba/fescar/server/lock/LockManagerTest.java b/server/src/test/java/com/alibaba/fescar/server/lock/LockManagerTest.java
new file mode 100644
index 000000000..aa32984e7
--- /dev/null
+++ b/server/src/test/java/com/alibaba/fescar/server/lock/LockManagerTest.java
@@ -0,0 +1,100 @@
+/*
+ *  Copyright 1999-2018 Alibaba Group Holding Ltd.
+ *
+ *  Licensed 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 com.alibaba.fescar.server.lock;
+
+import com.alibaba.fescar.core.model.BranchType;
+import com.alibaba.fescar.server.UUIDGenerator;
+import com.alibaba.fescar.server.session.BranchSession;
+import org.junit.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+/**
+ * @author tianming.xm@gmail.com
+ * @since 2019/1/23
+ */
+public class LockManagerTest {
+
+    @Test(dataProvider = "branchSessionProvider")
+    public void acquireLock_success(BranchSession branchSession) throws Exception{
+        LockManager lockManager = LockManagerFactory.get();
+        Assert.assertTrue(lockManager.acquireLock(branchSession));
+    }
+
+    @Test(dataProvider = "branchSessionsProvider")
+    public void acquireLock_failed(BranchSession branchSession1,BranchSession branchSession2) throws Exception{
+        LockManager lockManager = LockManagerFactory.get();
+        Assert.assertTrue(lockManager.acquireLock(branchSession1));
+        Assert.assertFalse(lockManager.acquireLock(branchSession2));
+    }
+
+    @Test(dataProvider = "branchSessionProvider")
+    public void isLockableTest(BranchSession branchSession) throws Exception{
+        branchSession.setLockKey("t:4");
+        LockManager lockManager = LockManagerFactory.get();
+        Assert.assertTrue(lockManager.isLockable(branchSession.getTransactionId(),branchSession.getResourceId(),branchSession.getLockKey()));
+        lockManager.acquireLock(branchSession);
+        branchSession.setTransactionId(UUIDGenerator.generateUUID());
+        Assert.assertFalse(lockManager.isLockable(branchSession.getTransactionId(),branchSession.getResourceId(),branchSession.getLockKey()));
+    }
+
+    @DataProvider
+    public static Object[][] branchSessionProvider() {
+        BranchSession branchSession = new BranchSession();
+        branchSession.setTransactionId(UUIDGenerator.generateUUID());
+        branchSession.setBranchId(0L);
+        branchSession.setClientId("c1");
+        branchSession.setResourceGroupId("my_test_tx_group");
+        branchSession.setResourceId("tb_1");
+        branchSession.setLockKey("t:0");
+        branchSession.setBranchType(BranchType.AT);
+        branchSession.setApplicationId("demo-child-app");
+        branchSession.setTxServiceGroup("my_test_tx_group");
+        branchSession.setApplicationData("{\"data\":\"test\"}");
+        branchSession.setBranchType(BranchType.AT);
+        return new Object[][] {{ branchSession}};
+    }
+
+    @DataProvider
+    public static Object[][] branchSessionsProvider() {
+        BranchSession branchSession1 = new BranchSession();
+        branchSession1.setTransactionId(UUIDGenerator.generateUUID());
+        branchSession1.setBranchId(1L);
+        branchSession1.setClientId("c1");
+        branchSession1.setResourceGroupId("my_test_tx_group");
+        branchSession1.setResourceId("tb_1");
+        branchSession1.setLockKey("t:1,2");
+        branchSession1.setBranchType(BranchType.AT);
+        branchSession1.setApplicationId("demo-child-app");
+        branchSession1.setTxServiceGroup("my_test_tx_group");
+        branchSession1.setApplicationData("{\"data\":\"test\"}");
+        branchSession1.setBranchType(BranchType.AT);
+
+        BranchSession branchSession2 = new BranchSession();
+        branchSession2.setTransactionId(UUIDGenerator.generateUUID());
+        branchSession2.setBranchId(2L);
+        branchSession2.setClientId("c1");
+        branchSession2.setResourceGroupId("my_test_tx_group");
+        branchSession2.setResourceId("tb_1");
+        branchSession2.setLockKey("t:1,2");
+        branchSession2.setBranchType(BranchType.AT);
+        branchSession2.setApplicationId("demo-child-app");
+        branchSession2.setTxServiceGroup("my_test_tx_group");
+        branchSession2.setApplicationData("{\"data\":\"test\"}");
+        branchSession2.setBranchType(BranchType.AT);
+        return new Object[][] {{ branchSession1,branchSession2}};
+    }
+}
diff --git a/server/src/test/java/com/alibaba/fescar/server/store/FileTransactionStoreManagerTest.java b/server/src/test/java/com/alibaba/fescar/server/store/FileTransactionStoreManagerTest.java
new file mode 100644
index 000000000..e48de1201
--- /dev/null
+++ b/server/src/test/java/com/alibaba/fescar/server/store/FileTransactionStoreManagerTest.java
@@ -0,0 +1,67 @@
+/*
+ *  Copyright 1999-2018 Alibaba Group Holding Ltd.
+ *
+ *  Licensed 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 com.alibaba.fescar.server.store;
+
+import com.alibaba.fescar.server.session.FileBasedSessionManager;
+import com.alibaba.fescar.server.session.GlobalSession;
+import com.alibaba.fescar.server.session.SessionManager;
+import org.junit.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.util.List;
+
+/**
+ * @author tianming.xm@gmail.com
+ * @since 2019/1/25
+ */
+public class FileTransactionStoreManagerTest {
+    private FileTransactionStoreManager fileTransactionStoreManager;
+
+    @BeforeClass
+    public void setUp() throws Exception{
+        SessionManager sessionManager = new FileBasedSessionManager("default","root.data");
+        fileTransactionStoreManager = new FileTransactionStoreManager("root.data",sessionManager);
+    }
+
+    @AfterClass
+    public void tearDown(){
+        fileTransactionStoreManager.shutdown();
+    }
+
+    @Test(dataProvider = "sessionProvider")
+    public void writeSessionTest(GlobalSession globalSession){
+        boolean result = fileTransactionStoreManager.writeSession(TransactionStoreManager.LogOperation.GLOBAL_ADD,globalSession);
+        Assert.assertTrue(result);
+    }
+
+    @Test(dataProvider = "sessionProvider")
+    public void readWriteStoreFromFileTest(GlobalSession globalSession){
+        fileTransactionStoreManager.writeSession(TransactionStoreManager.LogOperation.GLOBAL_ADD,globalSession);
+        List<TransactionWriteStore> stores = fileTransactionStoreManager.readWriteStoreFromFile(100,false);
+        Assert.assertNotNull(stores);
+        Assert.assertTrue(stores.size() > 0);
+    }
+
+    @DataProvider
+    public static Object[][] sessionProvider() {
+        GlobalSession globalSession = new GlobalSession("demo-app","my_test_tx_group","test",6000);
+        return new Object[][] {{ globalSession}};
+    }
+
+}