You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by ti...@apache.org on 2020/05/28 07:57:06 UTC

[servicecomb-mesher] branch master updated: Add unit test (#121)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 77370a8  Add  unit test (#121)
77370a8 is described below

commit 77370a885f6553107111667d40d72918c6c47320
Author: t-xinlin <t_...@sina.com>
AuthorDate: Thu May 28 15:56:54 2020 +0800

    Add  unit test (#121)
    
    * Remove ratelimiter handler
    
    * Add unit test for bootstrap
    
    * 修改bootstrap适配新的go-chassis
    
    * 修改go.mod适配新的go-chassis
    
    * UPdate travis.yaml
    
    * golint change
    
    * Fix: GoSecure Checker
    
    * Fix: travis.yam;
    
    * Fix bootstrap unit test
    
    * Fix: rm unused package
    
    * Fix: unit test error
    
    * Add unit test to dubbo protocl and http protocol modile.
    
    * Fix: 日志打印.
    
    * Add unit test to dubbo module.
    
    * Add UT for dubbo server.
    
    * Fix: unit test error.
    
    * Fix: unit test error.
    
    * Add unit test .
    
    * formate go file.
    
    * Fix: Unit test error.
    
    * Fix: Unit test error.
    
    Co-authored-by: “t_xinlin@sina.com <Happy100>
---
 proxy/protocol/dubbo/client/dubbo_client_test.go   |  44 +++++-
 proxy/protocol/dubbo/dubbo/codec_test.go           |  26 ++++
 proxy/protocol/dubbo/schema/schema_test.go         | 115 +++++++++++++++-
 proxy/protocol/dubbo/server/server_test.go         | 152 +++++++++++++++++++++
 .../simpleRegistry/simple_registry_server_test.go  | 145 ++++++++++++++++++++
 proxy/protocol/dubbo/utils/buffer.go               |   5 +-
 proxy/protocol/dubbo/utils/buffer_test.go          | 100 ++++++++++++++
 .../dubbo_client_test.go => utils/bytes_test.go}   |  46 +++++--
 proxy/protocol/dubbo/utils/msgqueue_test.go        | 116 ++++++++++++++++
 proxy/protocol/dubbo/utils/thrmgr_test.go          |  47 +++++++
 proxy/protocol/dubbo/utils/typeutil.go             |   5 +-
 proxy/protocol/dubbo/utils/typeutil_test.go        | 147 ++++++++++++++++++++
 12 files changed, 921 insertions(+), 27 deletions(-)

diff --git a/proxy/protocol/dubbo/client/dubbo_client_test.go b/proxy/protocol/dubbo/client/dubbo_client_test.go
index 3fb9fec..67a6273 100644
--- a/proxy/protocol/dubbo/client/dubbo_client_test.go
+++ b/proxy/protocol/dubbo/client/dubbo_client_test.go
@@ -18,11 +18,13 @@
 package dubboclient
 
 import (
-	"testing"
-	"time"
-
+	"github.com/apache/servicecomb-mesher/proxy/protocol/dubbo/dubbo"
 	"github.com/go-chassis/go-chassis/core/lager"
 	"github.com/stretchr/testify/assert"
+	"net/http"
+	"net/http/httptest"
+	"net/url"
+	"testing"
 )
 
 func init() {
@@ -33,8 +35,38 @@ func init() {
 }
 
 func TestClientMgr_GetClient(t *testing.T) {
+	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		w.WriteHeader(http.StatusOK)
+	}))
+
+	addr := ts.URL
+	u, _ := url.Parse(ts.URL)
+	addr = u.Host
 	clientMgr := NewClientMgr()
-	c, err := clientMgr.GetClient("127.0.0.1:30101", time.Second*5)
-	assert.Error(t, err)
-	assert.Nil(t, c)
+	// case timeout=0
+	c, err := clientMgr.GetClient(addr, 0)
+	assert.NoError(t, err)
+	assert.NotNil(t, c)
+	c.close()
+
+	c, err = clientMgr.GetClient(addr, 0)
+	assert.NoError(t, err)
+	assert.NotNil(t, c)
+
+	req := dubbo.NewDubboRequest()
+	c.Send(req)
+
+	// case RspCallBack
+	resp := &dubbo.DubboRsp{}
+	resp.Init()
+	resp.SetStatus(dubbo.ServerError)
+	c.RspCallBack(resp)
+
+	// case get addr
+	c.GetAddr()
+
+	// case net error
+	ts.Close()
+	clientMgr.GetClient(addr, 0)
+
 }
diff --git a/proxy/protocol/dubbo/dubbo/codec_test.go b/proxy/protocol/dubbo/dubbo/codec_test.go
index 1586341..771f5ae 100644
--- a/proxy/protocol/dubbo/dubbo/codec_test.go
+++ b/proxy/protocol/dubbo/dubbo/codec_test.go
@@ -29,10 +29,13 @@ import (
 func TestDubboCodec_DecodeDubboReqBody(t *testing.T) {
 	t.Log("If returns of rbf.ReadObject() is nil, should not panic")
 	d := &DubboCodec{}
+
+	req := NewDubboRequest()
 	resp := &DubboRsp{}
 	resp.Init()
 	resp.SetStatus(ServerError)
 
+	wbf := &util.WriteBuffer{}
 	rbf := &util.ReadBuffer{}
 	rbf.SetBuffer([]byte{hessian.BC_NULL})
 	c := make([]byte, 10)
@@ -43,5 +46,28 @@ func TestDubboCodec_DecodeDubboReqBody(t *testing.T) {
 	obj, err := rbf.ReadObject()
 	assert.Nil(t, err)
 	assert.Nil(t, obj)
+
+	assert.Equal(t, Hessian2, d.GetContentTypeID())
+	// case EncodeDubboRsp
+	d.EncodeDubboRsp(resp, wbf)
+
+	// case EncodeDubboReq
+	d.EncodeDubboReq(req, wbf)
+
+	// case DecodeDubboRspBody
 	d.DecodeDubboRspBody(rbf, resp)
+
+	// case DecodeDubboReqBodyForRegstry
+	d.DecodeDubboReqBodyForRegstry(req, rbf)
+	headBuf := make([]byte, HeaderLength)
+	bodyLen := 0
+
+	// case DecodeDubboReqHead
+	d.DecodeDubboReqHead(req, headBuf, &bodyLen)
+	bodyLen = 0
+
+	// case DecodeDubboRsqHead
+	d.DecodeDubboRsqHead(resp, headBuf, &bodyLen)
+
+	GCurMSGID = 0
 }
diff --git a/proxy/protocol/dubbo/schema/schema_test.go b/proxy/protocol/dubbo/schema/schema_test.go
index ce68475..362e94e 100644
--- a/proxy/protocol/dubbo/schema/schema_test.go
+++ b/proxy/protocol/dubbo/schema/schema_test.go
@@ -18,10 +18,18 @@
 package schema
 
 import (
+	"github.com/go-chassis/go-chassis/core/config"
+	"github.com/go-chassis/go-chassis/core/lager"
+	"github.com/go-chassis/go-chassis/core/registry"
 	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/mock"
 	"testing"
 )
 
+func init() {
+	lager.Init(&lager.Options{LoggerLevel: "DEBUG"})
+}
+
 func Test_GetRspSchema(t *testing.T) {
 	res := make(map[string]*MethRespond, 0)
 	res["200"] = &MethRespond{
@@ -45,15 +53,16 @@ func Test_GetParamNameAndWhere(t *testing.T) {
 		Status: "200",
 	}
 
-	mParams := []MethParam{MethParam{
+	mParams := []MethParam{{
 		Name:  "para1",
 		Where: "query",
 		Indx:  0,
-	}, MethParam{
+	}, {
 		Name:  "para2",
 		Where: "body",
 		Indx:  1,
-	}}
+	},
+	}
 
 	m := DefMethod{
 		ownerSvc: "svc",
@@ -85,15 +94,16 @@ func Test_GetParamSchema(t *testing.T) {
 		Status: "200",
 	}
 
-	mParams := []MethParam{MethParam{
+	mParams := []MethParam{{
 		Name:  "para1",
 		Where: "query",
 		Indx:  0,
-	}, MethParam{
+	}, {
 		Name:  "para2",
 		Where: "body",
 		Indx:  1,
-	}}
+	},
+	}
 
 	m := DefMethod{
 		ownerSvc: "svc",
@@ -116,3 +126,96 @@ func Test_GetParamSchema(t *testing.T) {
 	assert.Nil(t, param)
 
 }
+
+// CovertSwaggerMethordToLocalMethord(&schema, &m, &meth)
+func Test_CovertSwaggerMethordToLocalMethord(t *testing.T) {
+	schema := &registry.SchemaContent{
+		Definition: map[string]registry.Definition{
+			"hello": {},
+		},
+	}
+	paras := make([]registry.Parameter, 0)
+	paras = append(paras, registry.Parameter{
+		Name: "Hello",
+		Type: "string",
+		Schema: registry.SchemaValue{
+			Type:      "string",
+			Reference: "hello",
+		},
+	}, registry.Parameter{
+		Name: "Hello1",
+		Type: "",
+		Schema: registry.SchemaValue{
+			Type:      "string",
+			Reference: "hello1",
+		},
+	}, registry.Parameter{
+		Name: "Hello2",
+		Type: "",
+		Schema: registry.SchemaValue{
+			Type:      "",
+			Reference: "hello1",
+		},
+	})
+
+	srcMethod := &registry.MethodInfo{
+		Parameters: paras,
+		Response: map[string]registry.Response{
+			"200": {
+				Schema: map[string]string{"type": "string"},
+			},
+			"201": {
+				Schema: map[string]string{"$ref": "/v/hello"},
+			},
+		},
+	}
+	distMeth := &DefMethod{}
+	CovertSwaggerMethordToLocalMethord(schema, srcMethod, distMeth)
+}
+
+func Test_GetSvcByInterface(t *testing.T) {
+	config.Init()
+
+	registry.DefaultContractDiscoveryService = new(MockContractDiscoveryService)
+	v := GetSvcByInterface("hello")
+	assert.NotNil(t, v)
+
+	svcToInterfaceCache.Set("hello", &registry.MicroService{}, 0)
+	// case has value
+	v = GetSvcByInterface("hello")
+	assert.NotNil(t, v)
+
+}
+
+func Test_GetMethodByInterface(t *testing.T) {
+	registry.DefaultContractDiscoveryService = new(MockContractDiscoveryService)
+	GetMethodByInterface("hello", "hello")
+}
+
+// ContractDiscoveryService struct for disco mock
+type MockContractDiscoveryService struct {
+	mock.Mock
+}
+
+func (m *MockContractDiscoveryService) GetMicroServicesByInterface(interfaceName string) (microservices []*registry.MicroService) {
+	microservices = append(microservices, &registry.MicroService{})
+	return
+}
+
+func (m *MockContractDiscoveryService) GetSchemaContentByInterface(interfaceName string) registry.SchemaContent {
+	return registry.SchemaContent{}
+}
+
+func (m *MockContractDiscoveryService) GetSchemaContentByServiceName(svcName, version, appID, env string) []*registry.SchemaContent {
+	var sc []*registry.SchemaContent
+	sc = append(sc, &registry.SchemaContent{
+		Paths: map[string]map[string]registry.MethodInfo{
+			"hello": {},
+		},
+	})
+	return nil
+}
+
+func (m *MockContractDiscoveryService) Close() error {
+	return nil
+}
diff --git a/proxy/protocol/dubbo/server/server_test.go b/proxy/protocol/dubbo/server/server_test.go
new file mode 100644
index 0000000..e1da29a
--- /dev/null
+++ b/proxy/protocol/dubbo/server/server_test.go
@@ -0,0 +1,152 @@
+/*
+ * 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 server
+
+import (
+	dubboclient "github.com/apache/servicecomb-mesher/proxy/protocol/dubbo/client"
+	"github.com/apache/servicecomb-mesher/proxy/protocol/dubbo/dubbo"
+	"sync"
+	"time"
+
+	//_ "github.com/apache/servicecomb-mesher/proxy/protocol/dubbo/client"
+	"github.com/go-chassis/go-chassis/core/config"
+	"github.com/go-chassis/go-chassis/core/config/model"
+	"github.com/go-chassis/go-chassis/core/lager"
+	"github.com/go-chassis/go-chassis/core/server"
+	//"github.com/go-chassis/go-chassis/core/client
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+func init() {
+	lager.Init(&lager.Options{LoggerLevel: "DEBUG"})
+}
+
+func TestDubboServer_Start(t *testing.T) {
+	//config.Init()
+
+	protoMap := make(map[string]model.Protocol)
+	config.GlobalDefinition = &model.GlobalCfg{
+		Cse: model.CseStruct{
+			Protocols: protoMap,
+		},
+	}
+
+	defaultChain := make(map[string]string)
+	defaultChain["default"] = ""
+
+	config.GlobalDefinition.Cse.Handler.Chain.Provider = defaultChain
+	config.GlobalDefinition.Cse.Handler.Chain.Consumer = defaultChain
+	config.MicroserviceDefinition = &model.MicroserviceCfg{}
+
+	f, err := server.GetServerFunc("dubbo")
+	assert.NoError(t, err)
+
+	// case split port error
+	s := f(server.Options{
+		Address:   "0.0.0.130201",
+		ChainName: "default",
+	})
+	err = s.Start()
+	assert.Error(t, err)
+
+	// case invalid host
+	s = f(server.Options{
+		Address:   "2.2.2.1990:30201",
+		ChainName: "default",
+	})
+	err = s.Start()
+	assert.Error(t, err)
+
+	// case listening error
+	s = f(server.Options{
+		Address:   "99.0.0.1:30201",
+		ChainName: "default",
+	})
+	err = s.Start()
+	assert.Error(t, err)
+
+	// case ok
+	s = f(server.Options{
+		Address:   "127.0.0.1:30201",
+		ChainName: "default",
+	})
+	err = s.Start()
+	assert.NoError(t, err)
+
+	s.Stop()
+	time.Sleep(time.Second * 5)
+}
+
+func TestDubboServer(t *testing.T) {
+	t.Log("Test dubbo server function")
+	config.Init()
+
+	protoMap := make(map[string]model.Protocol)
+	config.GlobalDefinition = &model.GlobalCfg{
+		Cse: model.CseStruct{
+			Protocols: protoMap,
+		},
+	}
+
+	defaultChain := make(map[string]string)
+	defaultChain["default"] = ""
+
+	config.GlobalDefinition.Cse.Handler.Chain.Provider = defaultChain
+	config.GlobalDefinition.Cse.Handler.Chain.Consumer = defaultChain
+	config.MicroserviceDefinition = &model.MicroserviceCfg{}
+
+	f, err := server.GetServerFunc("dubbo")
+	assert.NoError(t, err)
+	addr := "127.0.0.1:40201"
+	s := f(server.Options{
+		Address:   addr,
+		ChainName: "default",
+	})
+
+	s.Register(map[string]string{})
+
+	err = s.Start()
+	assert.NoError(t, err)
+
+	name := s.String()
+	assert.Equal(t, "dubbo", name)
+
+	var wg sync.WaitGroup
+	wg.Add(1)
+	go func(wg *sync.WaitGroup) {
+		defer wg.Done()
+		clientMgr := dubboclient.NewClientMgr()
+		var dubboClient *dubboclient.DubboClient
+		dubboClient, err := clientMgr.GetClient(addr, time.Second*5)
+		assert.NoError(t, err)
+
+		req := new(dubbo.Request)
+		req.SetMsgID(int64(11111111))
+		req.SetVersion("1.0.0")
+		req.SetEvent("ok")
+
+		_, err = dubboClient.Send(req)
+
+	}(&wg)
+
+	wg.Wait()
+
+	err = s.Stop()
+	assert.NoError(t, err)
+}
diff --git a/proxy/protocol/dubbo/simpleRegistry/simple_registry_server_test.go b/proxy/protocol/dubbo/simpleRegistry/simple_registry_server_test.go
new file mode 100644
index 0000000..e394b7c
--- /dev/null
+++ b/proxy/protocol/dubbo/simpleRegistry/simple_registry_server_test.go
@@ -0,0 +1,145 @@
+/*
+ * 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 simpleregistry
+
+import (
+	dubboclient "github.com/apache/servicecomb-mesher/proxy/protocol/dubbo/client"
+	"github.com/apache/servicecomb-mesher/proxy/protocol/dubbo/dubbo"
+	"github.com/apache/servicecomb-mesher/proxy/protocol/dubbo/proxy"
+	"github.com/go-chassis/go-chassis/core/config"
+	"github.com/go-chassis/go-chassis/core/config/model"
+	"github.com/go-chassis/go-chassis/core/lager"
+	"github.com/go-chassis/go-chassis/core/server"
+	"github.com/stretchr/testify/assert"
+	"sync"
+	"testing"
+	"time"
+)
+
+func init() {
+	lager.Init(&lager.Options{LoggerLevel: "DEBUG"})
+}
+
+func TestSimpleDubboRegistryServer_Start(t *testing.T) {
+	protoMap := make(map[string]model.Protocol)
+	config.GlobalDefinition = &model.GlobalCfg{
+		Cse: model.CseStruct{
+			Protocols: protoMap,
+		},
+	}
+
+	defaultChain := make(map[string]string)
+	defaultChain["default"] = ""
+
+	config.GlobalDefinition.Cse.Handler.Chain.Provider = defaultChain
+	config.GlobalDefinition.Cse.Handler.Chain.Consumer = defaultChain
+
+	f, err := server.GetServerFunc("dubboSimpleRegistry")
+	assert.NoError(t, err)
+
+	// case split port error
+	s := f(server.Options{
+		Address:   "0.0.0.10201",
+		ChainName: "default",
+	})
+	err = s.Start()
+	assert.Error(t, err)
+	// case invalid host
+	s = f(server.Options{
+		Address:   "2.2.2.1990:50201",
+		ChainName: "default",
+	})
+	err = s.Start()
+	assert.Error(t, err)
+
+	// case listening error
+	s = f(server.Options{
+		Address:   "99.0.0.1:30201",
+		ChainName: "default",
+	})
+	err = s.Start()
+	assert.Error(t, err)
+
+	// case ok
+	s = f(server.Options{
+		Address:   "127.0.0.1:50201",
+		ChainName: "default",
+	})
+	err = s.Start()
+	assert.NoError(t, err)
+
+	s.Stop()
+	time.Sleep(time.Second * 5)
+}
+
+func TestDubboServer(t *testing.T) {
+	t.Log("Test dubboSimpleRegistry server function")
+
+	protoMap := make(map[string]model.Protocol)
+	config.GlobalDefinition = &model.GlobalCfg{
+		Cse: model.CseStruct{
+			Protocols: protoMap,
+		},
+	}
+
+	defaultChain := make(map[string]string)
+	defaultChain["default"] = ""
+
+	config.GlobalDefinition.Cse.Handler.Chain.Provider = defaultChain
+	config.GlobalDefinition.Cse.Handler.Chain.Consumer = defaultChain
+
+	f, err := server.GetServerFunc("dubboSimpleRegistry")
+	assert.NoError(t, err)
+	addr := "127.0.0.1:30401"
+	s := f(server.Options{
+		Address:   addr,
+		ChainName: "default",
+	})
+
+	s.Register(map[string]string{})
+
+	err = s.Start()
+	assert.NoError(t, err)
+
+	name := s.String()
+	assert.Equal(t, "dubboSimpleRegistry", name)
+
+	var wg sync.WaitGroup
+	wg.Add(1)
+	go func(wg *sync.WaitGroup) {
+		defer wg.Done()
+		clientMgr := dubboclient.NewClientMgr()
+		var dubboClient *dubboclient.DubboClient
+		dubboClient, err := clientMgr.GetClient(addr, time.Second*5)
+		assert.NoError(t, err)
+
+		req := new(dubbo.Request)
+		req.SetMsgID(int64(11111111))
+		req.SetVersion("1.0.0")
+		req.SetEvent("ok")
+
+		_, err = dubboClient.Send(req)
+
+	}(&wg)
+
+	wg.Wait()
+
+	assert.True(t, dubboproxy.IsProvider)
+	err = s.Stop()
+	assert.NoError(t, err)
+}
diff --git a/proxy/protocol/dubbo/utils/buffer.go b/proxy/protocol/dubbo/utils/buffer.go
index 601bc8c..5617266 100644
--- a/proxy/protocol/dubbo/utils/buffer.go
+++ b/proxy/protocol/dubbo/utils/buffer.go
@@ -188,7 +188,10 @@ func (b *ReadBuffer) ReadObject() (interface{}, error) {
 //ReadString is a method to read buffer and return as string
 func (b *ReadBuffer) ReadString() string {
 	gh := hessian.NewGoHessian(nil, nil)
-	obj, _ := gh.ToObject2(b)
+	obj, err := gh.ToObject2(b)
+	if obj == nil || err != nil {
+		return ""
+	}
 	return obj.(string)
 }
 
diff --git a/proxy/protocol/dubbo/utils/buffer_test.go b/proxy/protocol/dubbo/utils/buffer_test.go
new file mode 100644
index 0000000..4be9347
--- /dev/null
+++ b/proxy/protocol/dubbo/utils/buffer_test.go
@@ -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 util
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestWriteBuffe(t *testing.T) {
+	var buffer WriteBuffer
+	// case size = 0
+	buffer.Init(0)
+	// case size 1024
+	buffer.Init(DefaultBufferSize)
+
+	// Write []byte
+	n, err := buffer.Write([]byte("byteDate"))
+	assert.NoError(t, err)
+	assert.Equal(t, len("byteDate"), n)
+
+	// Write byte
+	err = buffer.WriteByte(byte(12))
+	assert.NoError(t, err)
+
+	// Write bytes
+	n = buffer.WriteBytes([]byte("byteDate"))
+	assert.Equal(t, len("byteDate"), n)
+
+	// Write Object
+	m := make(map[string]string)
+	m["key_01"] = "value_01"
+	err = buffer.WriteObject(m)
+	assert.NoError(t, err)
+
+	// Written Bytes
+	buffer.Init(24)
+	n = buffer.WrittenBytes()
+	assert.Equal(t, 0, n)
+
+	buffer.WriteBytes([]byte("byteDate"))
+	n = buffer.WrittenBytes()
+	assert.Equal(t, len("byteDate"), n)
+
+	// Get Buf
+	b := buffer.GetBuf()
+	assert.Less(t, 0, len(b))
+
+}
+
+func TestReadBuffe(t *testing.T) {
+	var buffer WriteBuffer
+	buffer.Init(DefaultBufferSize)
+
+	// Write byte
+	err := buffer.WriteByte(byte(12))
+	assert.NoError(t, err)
+
+	var readBuffer ReadBuffer
+	readBuffer.SetBuffer(buffer.GetBuf())
+	b := readBuffer.ReadByte()
+	assert.Equal(t, byte(12), b)
+
+	// Write Object
+	m := make(map[string]string)
+	m["key_01"] = "value_01"
+	err = buffer.WriteObject(m)
+	assert.NoError(t, err)
+	m, err = readBuffer.ReadMap()
+	assert.NoError(t, err)
+	assert.Equal(t, "value_01", m["key_01"])
+
+	// Write bytes
+	n := buffer.WriteBytes([]byte("byteDate"))
+	assert.Equal(t, len("byteDate"), n)
+	bs := readBuffer.ReadBytes(len("byteDate"))
+	assert.Equal(t, "byteDate", string(bs))
+
+	err = buffer.WriteObject("string01")
+	assert.NoError(t, err)
+
+	str := readBuffer.ReadString()
+	assert.Equal(t, "string01", str)
+}
diff --git a/proxy/protocol/dubbo/client/dubbo_client_test.go b/proxy/protocol/dubbo/utils/bytes_test.go
similarity index 55%
copy from proxy/protocol/dubbo/client/dubbo_client_test.go
copy to proxy/protocol/dubbo/utils/bytes_test.go
index 3fb9fec..fa65997 100644
--- a/proxy/protocol/dubbo/client/dubbo_client_test.go
+++ b/proxy/protocol/dubbo/utils/bytes_test.go
@@ -15,26 +15,46 @@
  * limitations under the License.
  */
 
-package dubboclient
+package util
 
 import (
 	"testing"
-	"time"
 
-	"github.com/go-chassis/go-chassis/core/lager"
 	"github.com/stretchr/testify/assert"
 )
 
-func init() {
-	lager.Init(&lager.Options{
-		LoggerLevel:   "INFO",
-		RollingPolicy: "size",
-	})
+func TestLong2bytes_Bytes2long(t *testing.T) {
+	bytes := make([]byte, 8)
+	v := int64(12345)
+	Long2bytes(v, bytes, 0)
+
+	v1 := Bytes2long(bytes, 0)
+	assert.Equal(t, v, v1)
+}
+
+func TestShort2bytes_Bytes2short(t *testing.T) {
+	bytes := make([]byte, 2)
+	v := int(11)
+	Short2bytes(v, bytes, 0)
+	t.Log(bytes)
+
+	v1 := Bytes2short(bytes, 0)
+	assert.Equal(t, uint16(v), v1)
+}
+
+func TestInt2bytes_Bytes2int(t *testing.T) {
+	bytes := make([]byte, 4)
+	v := int(11)
+	Int2bytes(v, bytes, 0)
+	t.Log(bytes)
+
+	v1 := Bytes2int(bytes, 0)
+	assert.Equal(t, int32(v), v1)
 }
 
-func TestClientMgr_GetClient(t *testing.T) {
-	clientMgr := NewClientMgr()
-	c, err := clientMgr.GetClient("127.0.0.1:30101", time.Second*5)
-	assert.Error(t, err)
-	assert.Nil(t, c)
+func TestS2ByteSlice(t *testing.T) {
+	bytes := []string{"Hello", " ", "World"}
+	ss := S2ByteSlice(bytes)
+	t.Log(ss)
+	assert.Equal(t, 3, len(ss))
 }
diff --git a/proxy/protocol/dubbo/utils/msgqueue_test.go b/proxy/protocol/dubbo/utils/msgqueue_test.go
new file mode 100644
index 0000000..50bd428
--- /dev/null
+++ b/proxy/protocol/dubbo/utils/msgqueue_test.go
@@ -0,0 +1,116 @@
+/*
+ * 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 util
+
+import (
+	"container/list"
+	"github.com/stretchr/testify/assert"
+	"sync"
+	"testing"
+	"time"
+)
+
+func NewMsgQueueForTest(maxMsgNum int) *MsgQueue {
+	q := new(MsgQueue)
+	q.msgList = list.New()
+	q.mtx = new(sync.Mutex)
+	q.msgCount = 0
+	q.maxMsgNum = maxMsgNum
+	q.state = Actived
+	q.notEmptyCond = sync.NewCond(q.mtx)
+	q.notFullCond = sync.NewCond(q.mtx)
+	return q
+}
+
+func TestMsgQueue(t *testing.T) {
+	t.Run("case empty", func(t *testing.T) {
+		q := NewMsgQueueForTest(2)
+
+		// append msg
+		eMSG := "msg to send"
+		err := q.Enqueue(eMSG)
+		assert.NoError(t, err)
+
+		assert.Equal(t, false, q.isEmpty())
+		assert.Equal(t, false, q.isFull())
+
+		// pop msg
+		dMSG, err := q.Dequeue()
+		assert.NoError(t, err)
+		assert.Equal(t, eMSG, dMSG)
+
+		// case empty
+		done := make(chan struct{})
+		go func(done chan struct{}) {
+			dMSG, err = q.Dequeue()
+			assert.NoError(t, err)
+
+			// Deavtive
+			q.Deavtive()
+
+			// error
+			_, err = q.Dequeue()
+			assert.Error(t, err)
+
+			if done != nil {
+				close(done)
+			}
+
+		}(done)
+
+		select {
+		case <-time.After(time.Second * 10):
+		case <-done:
+		}
+
+	})
+
+	t.Run("case Full", func(t *testing.T) {
+		eMSG := "msg to send"
+		// case Full
+		q1 := NewMsgQueueForTest(2)
+		err := q1.Enqueue(eMSG)
+		assert.NoError(t, err)
+
+		err = q1.Enqueue(eMSG)
+		assert.NoError(t, err)
+		done1 := make(chan struct{})
+		go func(c chan struct{}) {
+			err = q1.Enqueue(eMSG)
+			t.Log(err)
+			assert.Error(t, err)
+
+			if c != nil {
+				close(c)
+			}
+
+		}(done1)
+
+		select {
+		case <-time.After(time.Second * 10):
+		case <-done1:
+		}
+
+		// Deavtive
+		q1.Deavtive()
+
+		// error
+		err = q1.Enqueue(eMSG)
+		assert.Error(t, err)
+	})
+}
diff --git a/proxy/protocol/dubbo/utils/thrmgr_test.go b/proxy/protocol/dubbo/utils/thrmgr_test.go
new file mode 100644
index 0000000..8f2a50d
--- /dev/null
+++ b/proxy/protocol/dubbo/utils/thrmgr_test.go
@@ -0,0 +1,47 @@
+/*
+* 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 util
+
+import (
+	"github.com/stretchr/testify/assert"
+	"testing"
+	"time"
+)
+
+func TestNewThreadGroupWait(t *testing.T) {
+	count := 0
+	var done chan struct{}
+	go func(done chan struct{}) {
+		var tgw *ThreadGroupWait
+		tgw = NewThreadGroupWait()
+		tgw.Add(1)
+		go func(tgw *ThreadGroupWait) {
+			defer tgw.Done()
+			count++
+		}(tgw)
+		tgw.Wait()
+		close(done)
+	}(done)
+
+	select {
+	case <-time.After(time.Second * 2):
+	case <-done:
+	}
+	assert.Equal(t, 1, count)
+
+}
diff --git a/proxy/protocol/dubbo/utils/typeutil.go b/proxy/protocol/dubbo/utils/typeutil.go
index e7e10e5..18119d3 100644
--- a/proxy/protocol/dubbo/utils/typeutil.go
+++ b/proxy/protocol/dubbo/utils/typeutil.go
@@ -114,7 +114,10 @@ func init() {
 
 //ArrayToQueryString is a function which converts array to a string
 func ArrayToQueryString(key string, inlst interface{}) string {
-	lst := inlst.([]interface{})
+	lst, ok := inlst.([]interface{})
+	if !ok {
+		return ""
+	}
 	var retstr = ""
 	for i := 0; i < len(lst); i++ {
 		tmp := lst[i]
diff --git a/proxy/protocol/dubbo/utils/typeutil_test.go b/proxy/protocol/dubbo/utils/typeutil_test.go
new file mode 100644
index 0000000..e861e86
--- /dev/null
+++ b/proxy/protocol/dubbo/utils/typeutil_test.go
@@ -0,0 +1,147 @@
+/*
+* 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 util
+
+import (
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+func TestArrayToQueryString(t *testing.T) {
+	key := "key_01"
+	value := []interface{}{"value01", "value02"}
+	t.Log(ArrayToQueryString(key, value))
+
+}
+
+func TestObjectToString(t *testing.T) {
+	// case java string
+	str, err := ObjectToString(JavaString, "string01")
+	assert.NoError(t, err)
+	assert.Equal(t, "string01", str)
+
+	str, err = ObjectToString(JavaString, "")
+	assert.NoError(t, err)
+	assert.Equal(t, "", str)
+
+	// case java byte
+	str, err = ObjectToString(JavaByte, "9")
+	assert.NoError(t, err)
+	assert.Equal(t, "9", str)
+
+	// case java short
+	str, err = ObjectToString(JavaShort, "9")
+	assert.NoError(t, err)
+	assert.Equal(t, "9", str)
+
+	// case java Integer
+	str, err = ObjectToString(JavaInteger, "9")
+	assert.NoError(t, err)
+	assert.Equal(t, "9", str)
+
+	// case java Long
+	str, err = ObjectToString(JavaLong, "9")
+	assert.NoError(t, err)
+	assert.Equal(t, "9", str)
+
+	// case java Float
+	str, err = ObjectToString(JavaFloat, "9.01")
+	assert.NoError(t, err)
+	assert.Equal(t, "9.01", str)
+
+	// case java Float
+	str, err = ObjectToString(JavaDouble, "9.01")
+	assert.NoError(t, err)
+	assert.Equal(t, "9.01", str)
+
+	// case java Boolean
+	str, err = ObjectToString(JavaBoolean, "false")
+	assert.NoError(t, err)
+	assert.Equal(t, "false", str)
+
+	// case java Array
+	str, err = ObjectToString(JavaArray, "[1,2,3,4]")
+	assert.NoError(t, err)
+
+	str, err = ObjectToString(SchemaArray, "[1,2,3,4]")
+	assert.NoError(t, err)
+
+	// case java Array
+	data := struct {
+		SvcName string
+		Version int
+	}{"name", 100}
+
+	str, err = ObjectToString(JavaObject, data)
+	assert.NoError(t, err)
+
+	str, err = ObjectToString(SchemaObject, data)
+	assert.NoError(t, err)
+
+	// Default type
+	str, err = ObjectToString("Default type", "Hi")
+	assert.NoError(t, err)
+
+	// case value == nil
+	str, err = ObjectToString(SchemaObject, nil)
+	assert.NoError(t, err)
+	assert.Equal(t, 0, len(str))
+}
+
+func TestRestByteToValue(t *testing.T) {
+	// case java string
+	str, err := RestByteToValue(JavaString, []byte("string01"))
+	assert.NoError(t, err)
+	assert.Equal(t, "string01", str)
+
+	// case java short
+	bytes := make([]byte, 2)
+	v := int(11)
+	Short2bytes(v, bytes, 0)
+
+	str, err = RestByteToValue(JavaShort, bytes)
+	assert.NoError(t, err)
+	assert.Equal(t, int16(v), str)
+
+	// case java Integer
+	bytes = make([]byte, 4)
+	v = int(11)
+	Int2bytes(v, bytes, 0)
+
+	str, err = RestByteToValue(JavaInteger, bytes)
+	assert.NoError(t, err)
+	assert.Equal(t, int32(v), str)
+
+}
+
+func TestTypeDesToArgsObjArry(t *testing.T) {
+	arg := TypeDesToArgsObjArry(JavaString)
+	t.Log(arg)
+}
+
+func TestArgumen(t *testing.T) {
+	arg := Argument{JavaType: JavaString, Value: "string01"}
+	assert.Equal(t, JavaString, arg.GetJavaType())
+	assert.Equal(t, "string01", arg.GetValue())
+
+	arg.SetJavaType(JavaShort)
+	arg.SetValue(99)
+	assert.Equal(t, JavaShort, arg.GetJavaType())
+	assert.Equal(t, 99, arg.GetValue())
+
+}