You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by il...@apache.org on 2018/05/03 08:26:45 UTC

[incubator-dubbo] branch master updated: fix * imports issue (#1721)

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

iluo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-dubbo.git


The following commit(s) were added to refs/heads/master by this push:
     new 04ffae0  fix * imports issue (#1721)
04ffae0 is described below

commit 04ffae08869dec8a69977c47ec78f778dcb03649
Author: Huang YunKun <ht...@gmail.com>
AuthorDate: Thu May 3 16:26:42 2018 +0800

    fix * imports issue (#1721)
---
 .codecov.yml                                       |   3 +-
 .../dubbo/common/concurrent/ExecutionListTest.java |  99 ++++++++++++
 .../concurrent/ListenableFutureTaskTest.java       | 100 ++++++++++++
 .../com/alibaba/dubbo/common/io/BytesTest.java     | 172 ++++++++++++---------
 .../alibaba/dubbo/common/io/StreamUtilsTest.java   |  72 +++++++++
 .../common/io/UnsafeByteArrayInputStreamTest.java  |  87 +++++++++++
 .../common/io/UnsafeByteArrayOutputStreamTest.java |  78 ++++++++++
 .../dubbo/common/io/UnsafeStringReaderTest.java    |  72 +++++++++
 .../dubbo/common/io/UnsafeStringWriterTest.java    |  94 +++++++++++
 .../dubbo/common/logger/LoggerAdapterTest.java     |  74 +++++++++
 .../dubbo/common/logger/LoggerFactoryTest.java     |  61 ++++++++
 .../alibaba/dubbo/common/logger/LoggerTest.java    |  84 ++++++++++
 .../dubbo/common/logger/slf4j/Slf4jLoggerTest.java |  63 ++++++++
 .../common/logger/support/FailsafeLoggerTest.java  | 102 ++++++++++++
 .../com.alibaba.dubbo.common.logger.LoggerAdapter  |   1 +
 dubbo-common/src/test/resources/md5.testfile.txt   |   1 +
 16 files changed, 1093 insertions(+), 70 deletions(-)

diff --git a/.codecov.yml b/.codecov.yml
index d87923f..bd786c1 100644
--- a/.codecov.yml
+++ b/.codecov.yml
@@ -5,4 +5,5 @@ coverage:
       default:
         threshold: 0.1%
 ignore:
-  - "dubbo-demo/.*"
\ No newline at end of file
+  - "dubbo-demo/.*"
+  - "dubbo-common/src/main/java/com/alibaba/dubbo/common/json/*.java" #  internal JSON impl is deprecate, ignore test coverage for them
\ No newline at end of file
diff --git a/dubbo-common/src/test/java/com/alibaba/dubbo/common/concurrent/ExecutionListTest.java b/dubbo-common/src/test/java/com/alibaba/dubbo/common/concurrent/ExecutionListTest.java
new file mode 100644
index 0000000..16026e5
--- /dev/null
+++ b/dubbo-common/src/test/java/com/alibaba/dubbo/common/concurrent/ExecutionListTest.java
@@ -0,0 +1,99 @@
+/*
+ * 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 com.alibaba.dubbo.common.concurrent;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+public class ExecutionListTest {
+    private ExecutionList executionList;
+
+    @Before
+    public void setUp() throws Exception {
+        this.executionList = new ExecutionList();
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testAddNullRunnable() {
+        this.executionList.add(null, mock(Executor.class));
+    }
+
+    @Test
+    public void testAddRunnableToExecutor() {
+        Executor mockedExecutor = mock(Executor.class);
+
+        this.executionList.add(mock(Runnable.class), mockedExecutor);
+        this.executionList.execute();
+
+        verify(mockedExecutor).execute(any(Runnable.class));
+    }
+
+    @Test
+    public void testExecuteRunnableWithDefaultExecutor() throws InterruptedException {
+        final CountDownLatch countDownLatch = new CountDownLatch(1);
+        this.executionList.add(new Runnable() {
+            @Override
+            public void run() {
+                countDownLatch.countDown();
+            }
+        }, null);
+
+        this.executionList.execute();
+        countDownLatch.await();
+    }
+
+    @Test
+    public void testExceptionForExecutor() {
+        Executor mockedExecutor = mock(Executor.class);
+        doThrow(new RuntimeException()).when(mockedExecutor).execute(any(Runnable.class));
+
+        this.executionList.add(mock(Runnable.class), mockedExecutor);
+        this.executionList.execute();
+    }
+
+    @Test
+    public void testNotRunSameRunnableTwice() {
+        Executor mockedExecutor = mock(Executor.class);
+
+        this.executionList.add(mock(Runnable.class), mockedExecutor);
+
+        this.executionList.execute();
+        this.executionList.execute();
+
+        verify(mockedExecutor).execute(any(Runnable.class));
+    }
+
+    @Test
+    public void testRunImmediatelyAfterExecuted() {
+        Executor mockedExecutor = mock(Executor.class);
+
+        this.executionList.add(mock(Runnable.class), mockedExecutor);
+        this.executionList.execute();
+        this.executionList.add(mock(Runnable.class), mockedExecutor);
+
+        verify(mockedExecutor, times(2)).execute(any(Runnable.class));
+    }
+}
\ No newline at end of file
diff --git a/dubbo-common/src/test/java/com/alibaba/dubbo/common/concurrent/ListenableFutureTaskTest.java b/dubbo-common/src/test/java/com/alibaba/dubbo/common/concurrent/ListenableFutureTaskTest.java
new file mode 100644
index 0000000..cd11f8f
--- /dev/null
+++ b/dubbo-common/src/test/java/com/alibaba/dubbo/common/concurrent/ListenableFutureTaskTest.java
@@ -0,0 +1,100 @@
+/*
+ * 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 com.alibaba.dubbo.common.concurrent;
+
+import org.junit.Test;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+public class ListenableFutureTaskTest {
+    @Test
+    public void testCreate() throws InterruptedException {
+        final CountDownLatch countDownLatch = new CountDownLatch(1);
+        ListenableFutureTask<Boolean> futureTask = ListenableFutureTask.create(new Callable<Boolean>() {
+            @Override
+            public Boolean call() throws Exception {
+                countDownLatch.countDown();
+                return true;
+            }
+        });
+        futureTask.run();
+        countDownLatch.await();
+    }
+
+    @Test
+    public void testRunnableResponse() throws ExecutionException, InterruptedException {
+        ListenableFutureTask<Boolean> futureTask = ListenableFutureTask.create(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    Thread.sleep(500);
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                }
+            }
+        }, true);
+        futureTask.run();
+
+        Boolean result = futureTask.get();
+        assertThat(result, is(true));
+    }
+
+    @Test
+    public void testListener() throws InterruptedException {
+        ListenableFutureTask<String> futureTask = ListenableFutureTask.create(new Callable<String>() {
+            @Override
+            public String call() throws Exception {
+                Thread.sleep(500);
+                return "hello";
+            }
+        });
+        final CountDownLatch countDownLatch = new CountDownLatch(1);
+        futureTask.addListener(new Runnable() {
+            @Override
+            public void run() {
+                countDownLatch.countDown();
+            }
+        });
+        futureTask.run();
+        countDownLatch.await();
+    }
+
+
+    @Test
+    public void testCustomExecutor() {
+        Executor mockedExecutor = mock(Executor.class);
+        ListenableFutureTask<Integer> futureTask = ListenableFutureTask.create(new Callable<Integer>() {
+            @Override
+            public Integer call() throws Exception {
+                return 0;
+            }
+        });
+        futureTask.addListener(mock(Runnable.class), mockedExecutor);
+        futureTask.run();
+
+        verify(mockedExecutor).execute(any(Runnable.class));
+    }
+}
\ No newline at end of file
diff --git a/dubbo-common/src/test/java/com/alibaba/dubbo/common/io/BytesTest.java b/dubbo-common/src/test/java/com/alibaba/dubbo/common/io/BytesTest.java
index cfdf4d8..83c5eb5 100644
--- a/dubbo-common/src/test/java/com/alibaba/dubbo/common/io/BytesTest.java
+++ b/dubbo-common/src/test/java/com/alibaba/dubbo/common/io/BytesTest.java
@@ -16,100 +16,134 @@
  */
 package com.alibaba.dubbo.common.io;
 
-import junit.framework.TestCase;
-import org.junit.Assert;
-
-public class BytesTest extends TestCase {
-    private static final byte[] b1 = "adpfioha;eoh;aldfadl;kfadslkfdajfio123431241235123davas;odvwe;lmzcoqpwoewqogineopwqihwqetup\n\tejqf;lajsfd中文字符0da0gsaofdsf==adfasdfs".getBytes();
-    static byte[] bytes1 = {3, 12, 14, 41, 12, 2, 3, 12, 4, 67, 23};
-    static byte[] bytes2 = {3, 12, 14, 41, 12, 2, 3, 12, 4, 67};
-
-    private static void assertSame(byte[] b1, byte[] b2) {
-        assertEquals(b1.length, b2.length);
-        for (int i = 0; i < b1.length; i++)
-            assertEquals(b1[i], b2[i]);
-    }
+import org.junit.Test;
 
-    // tb-remoting codec method.
-    static public byte[] int2bytes(int x) {
-        byte[] bb = new byte[4];
-        bb[0] = (byte) (x >> 24);
-        bb[1] = (byte) (x >> 16);
-        bb[2] = (byte) (x >> 8);
-        bb[3] = (byte) (x >> 0);
-        return bb;
-    }
+import java.io.File;
+import java.io.IOException;
 
-    static public int bytes2int(byte[] bb, int idx) {
-        return ((bb[idx + 0] & 0xFF) << 24)
-                | ((bb[idx + 1] & 0xFF) << 16)
-                | ((bb[idx + 2] & 0xFF) << 8)
-                | ((bb[idx + 3] & 0xFF) << 0);
-    }
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
 
-    static public byte[] long2bytes(long x) {
-        byte[] bb = new byte[8];
-        bb[0] = (byte) (x >> 56);
-        bb[1] = (byte) (x >> 48);
-        bb[2] = (byte) (x >> 40);
-        bb[3] = (byte) (x >> 32);
-        bb[4] = (byte) (x >> 24);
-        bb[5] = (byte) (x >> 16);
-        bb[6] = (byte) (x >> 8);
-        bb[7] = (byte) (x >> 0);
-        return bb;
-    }
-
-    static public long bytes2long(byte[] bb, int idx) {
-        return (((long) bb[idx + 0] & 0xFF) << 56)
-                | (((long) bb[idx + 1] & 0xFF) << 48)
-                | (((long) bb[idx + 2] & 0xFF) << 40)
-                | (((long) bb[idx + 3] & 0xFF) << 32)
-                | (((long) bb[idx + 4] & 0xFF) << 24)
-                | (((long) bb[idx + 5] & 0xFF) << 16)
-                | (((long) bb[idx + 6] & 0xFF) << 8)
-                | (((long) bb[idx + 7] & 0xFF) << 0);
-    }
+public class BytesTest {
+    private final byte[] b1 = "adpfioha;eoh;aldfadl;kfadslkfdajfio123431241235123davas;odvwe;lmzcoqpwoewqogineopwqihwqetup\n\tejqf;lajsfd中文字符0da0gsaofdsf==adfasdfs".getBytes();
+    private final String C64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; //default base64.
+    private byte[] bytes1 = {3, 12, 14, 41, 12, 2, 3, 12, 4, 67, 23};
+    private byte[] bytes2 = {3, 12, 14, 41, 12, 2, 3, 12, 4, 67};
 
+    @Test
     public void testMain() throws Exception {
         short s = (short) 0xabcd;
-        assertEquals(s, Bytes.bytes2short(Bytes.short2bytes(s)));
+        assertThat(s, is(Bytes.bytes2short(Bytes.short2bytes(s))));
 
         int i = 198284;
-        assertEquals(i, Bytes.bytes2int(Bytes.int2bytes(i)));
+        assertThat(i, is(Bytes.bytes2int(Bytes.int2bytes(i))));
 
-        long l = 13841747174l;
-        assertEquals(l, Bytes.bytes2long(Bytes.long2bytes(l)));
+        long l = 13841747174L;
+        assertThat(l, is(Bytes.bytes2long(Bytes.long2bytes(l))));
 
         float f = 1.3f;
-        assertEquals(f, Bytes.bytes2float(Bytes.float2bytes(f)));
+        assertThat(f, is(Bytes.bytes2float(Bytes.float2bytes(f))));
 
         double d = 11213.3;
-        assertEquals(d, Bytes.bytes2double(Bytes.double2bytes(d)));
+        assertThat(d, is(Bytes.bytes2double(Bytes.double2bytes(d))));
+
+        assertThat(Bytes.int2bytes(i), is(int2bytes(i)));
+        assertThat(Bytes.long2bytes(l), is(long2bytes(l)));
+
+        String str = Bytes.bytes2base64("dubbo".getBytes());
+        byte[] bytes = Bytes.base642bytes(str, 0, str.length());
+        assertThat(bytes, is("dubbo".getBytes()));
 
-        assertSame(Bytes.int2bytes(i), int2bytes(i));
-        assertSame(Bytes.long2bytes(l), long2bytes(l));
+        byte[] bytesWithC64 = Bytes.base642bytes(str, C64);
+        assertThat(bytesWithC64, is(bytes));
     }
 
-    public void testBase64() throws Exception {
-        String str = Bytes.bytes2base64(b1);
-        byte[] b2 = Bytes.base642bytes(str);
-        assertSame(b1, b2);
+    @Test(expected = IllegalArgumentException.class)
+    public void testWrongBase64Code() {
+        Bytes.bytes2base64("dubbo".getBytes(), 0, 1, new char[]{'a'});
     }
 
-    public void testBase64_s2b2s_FailCaseLog() throws Exception {
+    @Test(expected = IndexOutOfBoundsException.class)
+    public void testWrongOffSet() {
+        Bytes.bytes2base64("dubbo".getBytes(), -1, 1);
+    }
+
+    @Test(expected = IndexOutOfBoundsException.class)
+    public void testLargeLength() {
+        Bytes.bytes2base64("dubbo".getBytes(), 0, 100000);
+    }
+
+    @Test(expected = IndexOutOfBoundsException.class)
+    public void testSmallLength() {
+        Bytes.bytes2base64("dubbo".getBytes(), 0, -1);
+    }
+
+    @Test
+    public void testBase64S2b2sFailCaseLog() throws Exception {
         String s1 = Bytes.bytes2base64(bytes1);
         byte[] out1 = Bytes.base642bytes(s1);
-        Assert.assertArrayEquals(bytes1, out1);
-
+        assertThat(bytes1, is(out1));
 
         String s2 = Bytes.bytes2base64(bytes2);
         byte[] out2 = Bytes.base642bytes(s2);
-        Assert.assertArrayEquals(bytes2, out2);
+        assertThat(bytes2, is(out2));
     }
 
-    public void testHex() throws Exception {
+    @Test
+    public void testHex() {
         String str = Bytes.bytes2hex(b1);
-        assertSame(b1, Bytes.hex2bytes(str));
+        assertThat(b1, is(Bytes.hex2bytes(str)));
+    }
+
+    @Test
+    public void testMD5ForString() {
+        byte[] md5 = Bytes.getMD5("dubbo");
+        assertThat(md5, is(Bytes.base642bytes("qk4bjCzJ3u2W/gEu8uB1Kg==")));
+    }
+
+    @Test
+    public void testMD5ForFile() throws IOException {
+        byte[] md5 = Bytes.getMD5(new File(getClass().getClassLoader().getResource("md5.testfile.txt").getFile()));
+        assertThat(md5, is(Bytes.base642bytes("iNZ+5qHafVNPLJxHwLKJ3w==")));
+    }
+
+    @Test
+    public void testZip() throws IOException {
+        String s = "hello world";
+        byte[] zip = Bytes.zip(s.getBytes());
+        byte[] unzip = Bytes.unzip(zip);
+        assertThat(unzip, is(s.getBytes()));
+    }
+
+    @Test(expected = IndexOutOfBoundsException.class)
+    public void testBytes2HexWithWrongOffset() {
+        Bytes.bytes2hex("hello".getBytes(), -1, 1);
+    }
+
+    @Test(expected = IndexOutOfBoundsException.class)
+    public void testBytes2HexWithWrongLength() {
+        Bytes.bytes2hex("hello".getBytes(), 0, 6);
+    }
+
+    private byte[] int2bytes(int x) {
+        byte[] bb = new byte[4];
+        bb[0] = (byte) (x >> 24);
+        bb[1] = (byte) (x >> 16);
+        bb[2] = (byte) (x >> 8);
+        bb[3] = (byte) (x >> 0);
+        return bb;
+    }
+
+    private byte[] long2bytes(long x) {
+        byte[] bb = new byte[8];
+        bb[0] = (byte) (x >> 56);
+        bb[1] = (byte) (x >> 48);
+        bb[2] = (byte) (x >> 40);
+        bb[3] = (byte) (x >> 32);
+        bb[4] = (byte) (x >> 24);
+        bb[5] = (byte) (x >> 16);
+        bb[6] = (byte) (x >> 8);
+        bb[7] = (byte) (x >> 0);
+        return bb;
     }
 }
\ No newline at end of file
diff --git a/dubbo-common/src/test/java/com/alibaba/dubbo/common/io/StreamUtilsTest.java b/dubbo-common/src/test/java/com/alibaba/dubbo/common/io/StreamUtilsTest.java
index c6d8f0f..bf422c0 100644
--- a/dubbo-common/src/test/java/com/alibaba/dubbo/common/io/StreamUtilsTest.java
+++ b/dubbo-common/src/test/java/com/alibaba/dubbo/common/io/StreamUtilsTest.java
@@ -18,11 +18,14 @@ package com.alibaba.dubbo.common.io;
 
 import org.junit.Test;
 
+import java.io.IOException;
 import java.io.InputStream;
 import java.io.PushbackInputStream;
 
+import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
 
 public class StreamUtilsTest {
 
@@ -77,4 +80,73 @@ public class StreamUtilsTest {
         assertEquals(-1, is.read());
         assertEquals(-1, is.read());
     }
+
+    @Test
+    public void testLimitedInputStream() throws Exception {
+        InputStream is = StreamUtilsTest.class.getResourceAsStream("/StreamUtilsTest.txt");
+        assertThat(10, is(is.available()));
+
+        is = StreamUtils.limitedInputStream(is, 2);
+        assertThat(2, is(is.available()));
+        assertThat(is.markSupported(), is(true));
+
+        is.mark(0);
+        assertEquals((int) '0', is.read());
+        assertEquals((int) '1', is.read());
+        assertEquals(-1, is.read());
+
+        is.reset();
+        is.skip(1);
+        assertEquals((int) '1', is.read());
+
+        is.reset();
+        is.skip(-1);
+        assertEquals((int) '0', is.read());
+
+        is.reset();
+        byte[] bytes = new byte[2];
+        int read = is.read(bytes, 1, 1);
+        assertThat(read, is(1));
+
+        is.reset();
+        StreamUtils.skipUnusedStream(is);
+        assertEquals(-1, is.read());
+
+        is.close();
+    }
+
+    @Test(expected = IOException.class)
+    public void testMarkInputSupport() throws IOException {
+        InputStream is = StreamUtilsTest.class.getResourceAsStream("/StreamUtilsTest.txt");
+        is = StreamUtils.markSupportedInputStream(new PushbackInputStream(is), 1);
+
+        is.mark(1);
+        int read = is.read();
+        assertThat(read, is((int) '0'));
+
+        is.skip(1);
+        is.read();
+    }
+
+    @Test
+    public void testSkipForOriginMarkSupportInput() {
+        InputStream is = StreamUtilsTest.class.getResourceAsStream("/StreamUtilsTest.txt");
+        InputStream newIs = StreamUtils.markSupportedInputStream(is, 1);
+
+        assertThat(newIs, is(is));
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testReadEmptyByteArray() throws IOException {
+        InputStream is = StreamUtilsTest.class.getResourceAsStream("/StreamUtilsTest.txt");
+        is = StreamUtils.limitedInputStream(is, 2);
+        is.read(null, 0, 1);
+    }
+
+    @Test(expected = IndexOutOfBoundsException.class)
+    public void testReadWithWrongOffset() throws IOException {
+        InputStream is = StreamUtilsTest.class.getResourceAsStream("/StreamUtilsTest.txt");
+        is = StreamUtils.limitedInputStream(is, 2);
+        is.read(new byte[1], -1, 1);
+    }
 }
\ No newline at end of file
diff --git a/dubbo-common/src/test/java/com/alibaba/dubbo/common/io/UnsafeByteArrayInputStreamTest.java b/dubbo-common/src/test/java/com/alibaba/dubbo/common/io/UnsafeByteArrayInputStreamTest.java
new file mode 100644
index 0000000..361caf8
--- /dev/null
+++ b/dubbo-common/src/test/java/com/alibaba/dubbo/common/io/UnsafeByteArrayInputStreamTest.java
@@ -0,0 +1,87 @@
+/*
+ * 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 com.alibaba.dubbo.common.io;
+
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+public class UnsafeByteArrayInputStreamTest {
+    @Test
+    public void testMark() {
+        UnsafeByteArrayInputStream stream = new UnsafeByteArrayInputStream("abc".getBytes(), 1);
+        assertThat(stream.markSupported(), is(true));
+
+        stream.mark(2);
+        stream.read();
+        assertThat(stream.position(), is(2));
+        stream.reset();
+        assertThat(stream.position(), is(1));
+    }
+
+    @Test
+    public void testRead() throws IOException {
+        UnsafeByteArrayInputStream stream = new UnsafeByteArrayInputStream("abc".getBytes());
+        assertThat(stream.read(), is((int) 'a'));
+        assertThat(stream.available(), is(2));
+
+        stream.skip(1);
+        assertThat(stream.available(), is(1));
+
+        byte[] bytes = new byte[1];
+        int read = stream.read(bytes);
+        assertThat(read, is(1));
+        assertThat(bytes, is("c".getBytes()));
+
+        stream.reset();
+        assertThat(stream.position(), is(0));
+        assertThat(stream.size(), is(3));
+
+        stream.position(1);
+        assertThat(stream.read(), is((int) 'b'));
+    }
+
+    @Test(expected = IndexOutOfBoundsException.class)
+    public void testWrongLength() {
+        UnsafeByteArrayInputStream stream = new UnsafeByteArrayInputStream("abc".getBytes());
+        stream.read(new byte[1], 0, 100);
+    }
+
+    @Test(expected = IndexOutOfBoundsException.class)
+    public void testWrongOffset() {
+        UnsafeByteArrayInputStream stream = new UnsafeByteArrayInputStream("abc".getBytes());
+        stream.read(new byte[1], -1, 1);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testReadEmptyByteArray() {
+        UnsafeByteArrayInputStream stream = new UnsafeByteArrayInputStream("abc".getBytes());
+        stream.read(null, 0, 1);
+    }
+
+    @Test
+    public void testSkipZero() {
+        UnsafeByteArrayInputStream stream = new UnsafeByteArrayInputStream("abc".getBytes());
+        long skip = stream.skip(-1);
+
+        assertThat(skip, is(0L));
+        assertThat(stream.position(), is(0));
+    }
+}
\ No newline at end of file
diff --git a/dubbo-common/src/test/java/com/alibaba/dubbo/common/io/UnsafeByteArrayOutputStreamTest.java b/dubbo-common/src/test/java/com/alibaba/dubbo/common/io/UnsafeByteArrayOutputStreamTest.java
new file mode 100644
index 0000000..0227ec0
--- /dev/null
+++ b/dubbo-common/src/test/java/com/alibaba/dubbo/common/io/UnsafeByteArrayOutputStreamTest.java
@@ -0,0 +1,78 @@
+/*
+ * 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 com.alibaba.dubbo.common.io;
+
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+
+public class UnsafeByteArrayOutputStreamTest {
+    @Test(expected = IllegalArgumentException.class)
+    public void testWrongSize() {
+        new UnsafeByteArrayOutputStream(-1);
+    }
+
+    @Test
+    public void testWrite() {
+        UnsafeByteArrayOutputStream outputStream = new UnsafeByteArrayOutputStream(1);
+        outputStream.write((int) 'a');
+        outputStream.write("bc".getBytes(), 0, 2);
+
+        assertThat(outputStream.size(), is(3));
+        assertThat(outputStream.toString(), is("abc"));
+    }
+
+    @Test
+    public void testToByteBuffer() {
+        UnsafeByteArrayOutputStream outputStream = new UnsafeByteArrayOutputStream(1);
+        outputStream.write((int) 'a');
+
+        ByteBuffer byteBuffer = outputStream.toByteBuffer();
+        assertThat(byteBuffer.get(), is("a".getBytes()[0]));
+    }
+
+    @Test
+    public void testExtendLengthForBuffer() throws IOException {
+        UnsafeByteArrayOutputStream outputStream = new UnsafeByteArrayOutputStream(1);
+        for (int i = 0; i < 10; i++) {
+            outputStream.write(i);
+        }
+        assertThat(outputStream.size(), is(10));
+
+        OutputStream stream = mock(OutputStream.class);
+        outputStream.writeTo(stream);
+        Mockito.verify(stream).write(any(byte[].class), anyInt(), eq(10));
+    }
+
+    @Test
+    public void testToStringWithCharset() throws IOException {
+        UnsafeByteArrayOutputStream outputStream = new UnsafeByteArrayOutputStream();
+        outputStream.write("Hòa Bình".getBytes());
+
+        assertThat(outputStream.toString("UTF-8"), is("Hòa Bình"));
+    }
+}
\ No newline at end of file
diff --git a/dubbo-common/src/test/java/com/alibaba/dubbo/common/io/UnsafeStringReaderTest.java b/dubbo-common/src/test/java/com/alibaba/dubbo/common/io/UnsafeStringReaderTest.java
new file mode 100644
index 0000000..1bafe19
--- /dev/null
+++ b/dubbo-common/src/test/java/com/alibaba/dubbo/common/io/UnsafeStringReaderTest.java
@@ -0,0 +1,72 @@
+/*
+ * 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 com.alibaba.dubbo.common.io;
+
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+public class UnsafeStringReaderTest {
+    @Test
+    public void testRead() throws IOException {
+        UnsafeStringReader reader = new UnsafeStringReader("abc");
+        assertThat(reader.markSupported(), is(true));
+        assertThat(reader.read(), is((int) 'a'));
+        assertThat(reader.read(), is((int) 'b'));
+        assertThat(reader.read(), is((int) 'c'));
+        assertThat(reader.read(), is(-1));
+
+        reader.reset();
+        reader.mark(0);
+        assertThat(reader.read(), is((int) 'a'));
+
+        char[] chars = new char[2];
+        reader.read(chars);
+        reader.close();
+
+        assertThat(chars[0], is('b'));
+        assertThat(chars[1], is('c'));
+    }
+
+    @Test
+    public void testSkip() throws IOException {
+        UnsafeStringReader reader = new UnsafeStringReader("abc");
+        assertThat(reader.ready(), is(true));
+        reader.skip(1);
+        assertThat(reader.read(), is((int) 'b'));
+    }
+
+    @Test
+    public void testSkipTooLong() throws IOException {
+        UnsafeStringReader reader = new UnsafeStringReader("abc");
+
+        reader.skip(10);
+        long skip = reader.skip(10);
+
+        assertThat(skip, is(0L));
+    }
+
+    @Test(expected = IndexOutOfBoundsException.class)
+    public void testWrongLength() throws IOException {
+        UnsafeStringReader reader = new UnsafeStringReader("abc");
+        char[] chars = new char[1];
+        reader.read(chars, 0, 2);
+    }
+}
\ No newline at end of file
diff --git a/dubbo-common/src/test/java/com/alibaba/dubbo/common/io/UnsafeStringWriterTest.java b/dubbo-common/src/test/java/com/alibaba/dubbo/common/io/UnsafeStringWriterTest.java
new file mode 100644
index 0000000..c9f6b2e
--- /dev/null
+++ b/dubbo-common/src/test/java/com/alibaba/dubbo/common/io/UnsafeStringWriterTest.java
@@ -0,0 +1,94 @@
+/*
+ * 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 com.alibaba.dubbo.common.io;
+
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+public class UnsafeStringWriterTest {
+    @Test
+    public void testWrite() {
+        UnsafeStringWriter writer = new UnsafeStringWriter();
+        writer.write("a");
+        writer.write("abc", 1, 1);
+        writer.write(99);
+        writer.flush();
+        writer.close();
+
+        assertThat(writer.toString(), is("abc"));
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testNegativeSize() {
+        new UnsafeStringWriter(-1);
+    }
+
+    @Test
+    public void testAppend() {
+        UnsafeStringWriter writer = new UnsafeStringWriter();
+        writer.append("a");
+        writer.append("abc", 1, 2);
+        writer.append('c');
+        writer.flush();
+        writer.close();
+
+        assertThat(writer.toString(), is("abc"));
+    }
+
+    @Test
+    public void testAppendNull() {
+        UnsafeStringWriter writer = new UnsafeStringWriter();
+        writer.append(null);
+        writer.append(null, 0, 4);
+        writer.flush();
+        writer.close();
+
+        assertThat(writer.toString(), is("nullnull"));
+    }
+
+    @Test
+    public void testWriteNull() throws IOException {
+        UnsafeStringWriter writer = new UnsafeStringWriter(3);
+        char[] chars = new char[2];
+        chars[0] = 'a';
+        chars[1] = 'b';
+        writer.write(chars);
+        writer.write(chars, 0, 1);
+        writer.flush();
+        writer.close();
+
+        assertThat(writer.toString(), is("aba"));
+    }
+
+    @Test(expected = IndexOutOfBoundsException.class)
+    public void testWriteCharWithWrongLength() throws IOException {
+        UnsafeStringWriter writer = new UnsafeStringWriter();
+        char[] chars = new char[0];
+        writer.write(chars, 0, 1);
+    }
+
+    @Test(expected = IndexOutOfBoundsException.class)
+    public void testWriteCharWithWrongCombineLength() throws IOException {
+        UnsafeStringWriter writer = new UnsafeStringWriter();
+        char[] chars = new char[1];
+        writer.write(chars, 1, 1);
+    }
+}
diff --git a/dubbo-common/src/test/java/com/alibaba/dubbo/common/logger/LoggerAdapterTest.java b/dubbo-common/src/test/java/com/alibaba/dubbo/common/logger/LoggerAdapterTest.java
new file mode 100644
index 0000000..5aff03a
--- /dev/null
+++ b/dubbo-common/src/test/java/com/alibaba/dubbo/common/logger/LoggerAdapterTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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 com.alibaba.dubbo.common.logger;
+
+import com.alibaba.dubbo.common.logger.jcl.JclLogger;
+import com.alibaba.dubbo.common.logger.jcl.JclLoggerAdapter;
+import com.alibaba.dubbo.common.logger.jdk.JdkLogger;
+import com.alibaba.dubbo.common.logger.jdk.JdkLoggerAdapter;
+import com.alibaba.dubbo.common.logger.log4j.Log4jLogger;
+import com.alibaba.dubbo.common.logger.log4j.Log4jLoggerAdapter;
+import com.alibaba.dubbo.common.logger.slf4j.Slf4jLogger;
+import com.alibaba.dubbo.common.logger.slf4j.Slf4jLoggerAdapter;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+@RunWith(Parameterized.class)
+public class LoggerAdapterTest {
+    @Parameterized.Parameters
+    public static Collection<Object[]> data() {
+        return Arrays.asList(new Object[][]{
+                {JclLoggerAdapter.class, JclLogger.class},
+                {JdkLoggerAdapter.class, JdkLogger.class},
+                {Log4jLoggerAdapter.class, Log4jLogger.class},
+                {Slf4jLoggerAdapter.class, Slf4jLogger.class}
+        });
+    }
+
+    private Class loggerClass;
+    private LoggerAdapter loggerAdapter;
+
+    public LoggerAdapterTest(Class<? extends LoggerAdapter> loggerAdapterClass, Class<? extends Logger> loggerClass) throws Exception {
+        this.loggerClass = loggerClass;
+        this.loggerAdapter = loggerAdapterClass.newInstance();
+    }
+
+    @Test
+    public void testGetLogger() {
+        Logger logger = loggerAdapter.getLogger(this.getClass());
+        assertThat(logger.getClass().isAssignableFrom(this.loggerClass), is(true));
+
+        logger = loggerAdapter.getLogger(this.getClass().getSimpleName());
+        assertThat(logger.getClass().isAssignableFrom(this.loggerClass), is(true));
+    }
+
+    @Test
+    public void testLevel() {
+        for (Level targetLevel : Level.values()) {
+            loggerAdapter.setLevel(targetLevel);
+
+            assertThat(loggerAdapter.getLevel(), is(targetLevel));
+        }
+    }
+}
\ No newline at end of file
diff --git a/dubbo-common/src/test/java/com/alibaba/dubbo/common/logger/LoggerFactoryTest.java b/dubbo-common/src/test/java/com/alibaba/dubbo/common/logger/LoggerFactoryTest.java
new file mode 100644
index 0000000..65f6e46
--- /dev/null
+++ b/dubbo-common/src/test/java/com/alibaba/dubbo/common/logger/LoggerFactoryTest.java
@@ -0,0 +1,61 @@
+/*
+ * 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 com.alibaba.dubbo.common.logger;
+
+import org.junit.Test;
+
+import java.io.File;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.assertThat;
+
+public class LoggerFactoryTest {
+    @Test
+    public void testLoggerLevel() {
+        LoggerFactory.setLevel(Level.INFO);
+        Level level = LoggerFactory.getLevel();
+
+        assertThat(level, is(Level.INFO));
+    }
+
+    @Test
+    public void testGetLogFile() {
+        LoggerFactory.setLoggerAdapter("slf4j");
+        File file = LoggerFactory.getFile();
+
+        assertThat(file, is(nullValue()));
+    }
+
+    @Test
+    public void testAllLogLevel() {
+        for (Level targetLevel : Level.values()) {
+            LoggerFactory.setLevel(targetLevel);
+            Level level = LoggerFactory.getLevel();
+
+            assertThat(level, is(targetLevel));
+        }
+    }
+
+    @Test
+    public void testGetLogger() {
+        Logger logger1 = LoggerFactory.getLogger(this.getClass());
+        Logger logger2 = LoggerFactory.getLogger(this.getClass());
+
+        assertThat(logger1, is(logger2));
+    }
+}
\ No newline at end of file
diff --git a/dubbo-common/src/test/java/com/alibaba/dubbo/common/logger/LoggerTest.java b/dubbo-common/src/test/java/com/alibaba/dubbo/common/logger/LoggerTest.java
new file mode 100644
index 0000000..7e6cb41
--- /dev/null
+++ b/dubbo-common/src/test/java/com/alibaba/dubbo/common/logger/LoggerTest.java
@@ -0,0 +1,84 @@
+/*
+ * 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 com.alibaba.dubbo.common.logger;
+
+import com.alibaba.dubbo.common.logger.jcl.JclLoggerAdapter;
+import com.alibaba.dubbo.common.logger.jdk.JdkLoggerAdapter;
+import com.alibaba.dubbo.common.logger.log4j.Log4jLoggerAdapter;
+import com.alibaba.dubbo.common.logger.slf4j.Slf4jLoggerAdapter;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.assertThat;
+
+
+@RunWith(Parameterized.class)
+public class LoggerTest {
+    @Parameterized.Parameters
+    public static Collection<Object[]> data() {
+        return Arrays.asList(new Object[][]{
+                {JclLoggerAdapter.class},
+                {JdkLoggerAdapter.class},
+                {Log4jLoggerAdapter.class},
+                {Slf4jLoggerAdapter.class}
+        });
+    }
+
+    private Logger logger;
+
+    public LoggerTest(Class<? extends LoggerAdapter> loggerAdapter) throws Exception {
+        LoggerAdapter adapter = loggerAdapter.newInstance();
+        adapter.setLevel(Level.ALL);
+        this.logger = adapter.getLogger(this.getClass());
+    }
+
+    @Test
+    public void testAllLogMethod() {
+        logger.error("error");
+        logger.warn("warn");
+        logger.info("info");
+        logger.debug("debug");
+        logger.trace("info");
+
+        logger.error(new Exception("error"));
+        logger.warn(new Exception("warn"));
+        logger.info(new Exception("info"));
+        logger.debug(new Exception("debug"));
+        logger.trace(new Exception("trace"));
+
+        logger.error("error", new Exception("error"));
+        logger.warn("warn", new Exception("warn"));
+        logger.info("info", new Exception("info"));
+        logger.debug("debug", new Exception("debug"));
+        logger.trace("trace", new Exception("trace"));
+    }
+
+    @Test
+    public void testLevelEnable() {
+        assertThat(logger.isWarnEnabled(), not(nullValue()));
+        assertThat(logger.isTraceEnabled(), not(nullValue()));
+        assertThat(logger.isErrorEnabled(), not(nullValue()));
+        assertThat(logger.isInfoEnabled(), not(nullValue()));
+        assertThat(logger.isDebugEnabled(), not(nullValue()));
+    }
+}
\ No newline at end of file
diff --git a/dubbo-common/src/test/java/com/alibaba/dubbo/common/logger/slf4j/Slf4jLoggerTest.java b/dubbo-common/src/test/java/com/alibaba/dubbo/common/logger/slf4j/Slf4jLoggerTest.java
new file mode 100644
index 0000000..f0d79af
--- /dev/null
+++ b/dubbo-common/src/test/java/com/alibaba/dubbo/common/logger/slf4j/Slf4jLoggerTest.java
@@ -0,0 +1,63 @@
+/*
+ * 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 com.alibaba.dubbo.common.logger.slf4j;
+
+import org.junit.Test;
+import org.slf4j.Marker;
+import org.slf4j.spi.LocationAwareLogger;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.internal.verification.VerificationModeFactory.times;
+
+public class Slf4jLoggerTest {
+    @Test
+    public void testLocationAwareLogger() {
+        LocationAwareLogger locationAwareLogger = mock(LocationAwareLogger.class);
+        Slf4jLogger logger = new Slf4jLogger(locationAwareLogger);
+
+        logger.error("error");
+        ;
+
+        logger.warn("warn");
+        logger.info("info");
+        logger.debug("debug");
+        logger.trace("info");
+
+        verify(locationAwareLogger, times(5)).log(isNull(Marker.class), anyString(),
+                anyInt(), anyString(), isNull(Object[].class), isNull(Throwable.class));
+
+        logger.error(new Exception("error"));
+        logger.warn(new Exception("warn"));
+        logger.info(new Exception("info"));
+        logger.debug(new Exception("debug"));
+        logger.trace(new Exception("trace"));
+
+        logger.error("error", new Exception("error"));
+        logger.warn("warn", new Exception("warn"));
+        logger.info("info", new Exception("info"));
+        logger.debug("debug", new Exception("debug"));
+        logger.trace("trace", new Exception("trace"));
+
+        verify(locationAwareLogger, times(10)).log(isNull(Marker.class), anyString(),
+                anyInt(), anyString(), isNull(Object[].class), any(Throwable.class));
+    }
+}
\ No newline at end of file
diff --git a/dubbo-common/src/test/java/com/alibaba/dubbo/common/logger/support/FailsafeLoggerTest.java b/dubbo-common/src/test/java/com/alibaba/dubbo/common/logger/support/FailsafeLoggerTest.java
new file mode 100644
index 0000000..1b6cb42
--- /dev/null
+++ b/dubbo-common/src/test/java/com/alibaba/dubbo/common/logger/support/FailsafeLoggerTest.java
@@ -0,0 +1,102 @@
+/*
+ * 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 com.alibaba.dubbo.common.logger.support;
+
+import com.alibaba.dubbo.common.logger.Logger;
+import org.junit.Test;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+public class FailsafeLoggerTest {
+    @Test
+    public void testFailSafeForLoggingMethod() {
+        Logger failLogger = mock(Logger.class);
+        FailsafeLogger failsafeLogger = new FailsafeLogger(failLogger);
+
+        doThrow(new RuntimeException()).when(failLogger).error(anyString());
+        doThrow(new RuntimeException()).when(failLogger).warn(anyString());
+        doThrow(new RuntimeException()).when(failLogger).info(anyString());
+        doThrow(new RuntimeException()).when(failLogger).debug(anyString());
+        doThrow(new RuntimeException()).when(failLogger).trace(anyString());
+
+        failsafeLogger.error("error");
+        failsafeLogger.warn("warn");
+        failsafeLogger.info("info");
+        failsafeLogger.debug("debug");
+        failsafeLogger.trace("info");
+
+        doThrow(new RuntimeException()).when(failLogger).error(any(Throwable.class));
+        doThrow(new RuntimeException()).when(failLogger).warn(any(Throwable.class));
+        doThrow(new RuntimeException()).when(failLogger).info(any(Throwable.class));
+        doThrow(new RuntimeException()).when(failLogger).debug(any(Throwable.class));
+        doThrow(new RuntimeException()).when(failLogger).trace(any(Throwable.class));
+
+        failsafeLogger.error(new Exception("error"));
+        failsafeLogger.warn(new Exception("warn"));
+        failsafeLogger.info(new Exception("info"));
+        failsafeLogger.debug(new Exception("debug"));
+        failsafeLogger.trace(new Exception("trace"));
+
+        failsafeLogger.error("error", new Exception("error"));
+        failsafeLogger.warn("warn", new Exception("warn"));
+        failsafeLogger.info("info", new Exception("info"));
+        failsafeLogger.debug("debug", new Exception("debug"));
+        failsafeLogger.trace("trace", new Exception("trace"));
+    }
+
+    @Test
+    public void testSuccessLogger() {
+        Logger successLogger = mock(Logger.class);
+        FailsafeLogger failsafeLogger = new FailsafeLogger(successLogger);
+        failsafeLogger.error("error");
+        failsafeLogger.warn("warn");
+        failsafeLogger.info("info");
+        failsafeLogger.debug("debug");
+        failsafeLogger.trace("info");
+
+        verify(successLogger).error(anyString());
+        verify(successLogger).warn(anyString());
+        verify(successLogger).info(anyString());
+        verify(successLogger).debug(anyString());
+        verify(successLogger).trace(anyString());
+
+        failsafeLogger.error(new Exception("error"));
+        failsafeLogger.warn(new Exception("warn"));
+        failsafeLogger.info(new Exception("info"));
+        failsafeLogger.debug(new Exception("debug"));
+        failsafeLogger.trace(new Exception("trace"));
+
+        failsafeLogger.error("error", new Exception("error"));
+        failsafeLogger.warn("warn", new Exception("warn"));
+        failsafeLogger.info("info", new Exception("info"));
+        failsafeLogger.debug("debug", new Exception("debug"));
+        failsafeLogger.trace("trace", new Exception("trace"));
+    }
+
+    @Test(expected = RuntimeException.class)
+    public void testGetLogger() {
+        Logger failLogger = mock(Logger.class);
+        FailsafeLogger failsafeLogger = new FailsafeLogger(failLogger);
+
+        doThrow(new RuntimeException()).when(failLogger).error(anyString());
+        failsafeLogger.getLogger().error("should get error");
+    }
+}
\ No newline at end of file
diff --git a/dubbo-common/src/test/resources/META-INF/dubbo/internal/com.alibaba.dubbo.common.logger.LoggerAdapter b/dubbo-common/src/test/resources/META-INF/dubbo/internal/com.alibaba.dubbo.common.logger.LoggerAdapter
new file mode 100644
index 0000000..9f11f50
--- /dev/null
+++ b/dubbo-common/src/test/resources/META-INF/dubbo/internal/com.alibaba.dubbo.common.logger.LoggerAdapter
@@ -0,0 +1 @@
+slf4j=com.alibaba.dubbo.common.logger.slf4j.Slf4jLoggerAdapter
\ No newline at end of file
diff --git a/dubbo-common/src/test/resources/md5.testfile.txt b/dubbo-common/src/test/resources/md5.testfile.txt
new file mode 100644
index 0000000..bc7774a
--- /dev/null
+++ b/dubbo-common/src/test/resources/md5.testfile.txt
@@ -0,0 +1 @@
+hello world!
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
iluo@apache.org.