test: add common test lib
diff --git a/config_example/sys.config b/config_example/sys.config
index 3c88045..0d40be0 100644
--- a/config_example/sys.config
+++ b/config_example/sys.config
@@ -6,7 +6,7 @@
             {<<"com.ifcoder.demo.facade.User">>,[]}
         ]},
         {provider,[
-            {user_impl,user_behaviour,<<"com.ifcoder.demo.facade.User">>,[]}
+           % {user_impl,user_behaviour,<<"com.ifcoder.demo.facade.User">>,[]}
         ]}
         
     ]}
diff --git a/src/dubbo_consumer_pool.erl b/src/dubbo_consumer_pool.erl
index d1a2af1..c88c5eb 100644
--- a/src/dubbo_consumer_pool.erl
+++ b/src/dubbo_consumer_pool.erl
@@ -148,7 +148,7 @@
 %%--------------------------------------------------------------------
 %% @private
 %% @doc
-%% This function is called by a gen_se  rver when it is about to
+%% This function is called by a gen_server when it is about to
 %% terminate. It should be the opposite of Module:init/1 and do any
 %% necessary cleaning up. When it returns, the gen_server terminates
 %% with Reason. The return value is ignored.
@@ -270,7 +270,6 @@
         []->
             ok;
         ProviderNodeList->
-            io:format("ConnectionList ~p~n",[ProviderNodeList]),
             ProviderNodeList1 = lists_util:del_duplicate(ProviderNodeList),
             clean_connection_info(ProviderNodeList1)
     end,
diff --git a/src/dubboerl.app.src b/src/dubboerl.app.src
index 14b842b..ad95fde 100644
--- a/src/dubboerl.app.src
+++ b/src/dubboerl.app.src
@@ -5,7 +5,7 @@
   {mod, { dubboerl_app, []}},
   {applications,
    [kernel,
-    stdlib,xmerl,eunit,erlzk,logger,poolboy,inets
+    stdlib,xmerl,eunit,erlzk,poolboy,inets
    ]},
   {env,[]},
   {modules, []},
diff --git a/src/dubboerl.erl b/src/dubboerl.erl
index a183d07..5cbaa78 100644
--- a/src/dubboerl.erl
+++ b/src/dubboerl.erl
@@ -16,8 +16,8 @@
 -export([init/0,start_consumer/0,start_provider/0]).
 
 init()->
-    start_consumer(),
-    start_provider(),
+    ok=start_consumer(),
+    ok=start_provider(),
     ok.
 
 
diff --git a/test/consumer_SUITE.erl b/test/consumer_SUITE.erl
new file mode 100644
index 0000000..f6cf0d3
--- /dev/null
+++ b/test/consumer_SUITE.erl
@@ -0,0 +1,126 @@
+%%%-------------------------------------------------------------------
+%%% @author dlive
+%%% @copyright (C) 2019, <COMPANY>
+%%% @doc
+%%%
+%%% @end
+%%% Created : 02. May 2019 17:10
+%%%-------------------------------------------------------------------
+-module(consumer_SUITE).
+-author("dlive").
+
+%% API
+-export([]).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+suite() ->
+  [{timetrap,{seconds,50}}].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%%               Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+  application:ensure_all_started(dubboerl),
+  Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> term() | {save_config,Config1}
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+  ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_group(GroupName, Config0) ->
+%%               Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_group(_GroupName, Config) ->
+  Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_group(GroupName, Config0) ->
+%%               term() | {save_config,Config1}
+%% GroupName = atom()
+%% Config0 = Config1 = [tuple()]
+%%--------------------------------------------------------------------
+end_per_group(_GroupName, _Config) ->
+  ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%%               Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config) ->
+  Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%%               term() | {save_config,Config1} | {fail,Reason}
+%% TestCase = atom()
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+  ok.
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%%              repeat_until_any_ok | repeat_until_any_fail
+%% N = integer() | forever
+%%--------------------------------------------------------------------
+groups() ->
+  [
+    {consumer1,[sequence],[lib_type_register]}
+  ].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases | {skip,Reason}
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% TestCase = atom()
+%% Reason = term()
+%%--------------------------------------------------------------------
+all() ->
+  [{group,consumer1}].
+
+%%--------------------------------------------------------------------
+%% Function: TestCase() -> Info
+%% Info = [tuple()]
+%%--------------------------------------------------------------------
+lib_type_register() ->
+  [].
+
+%%--------------------------------------------------------------------
+%% Function: TestCase(Config0) ->
+%%               ok | exit() | {skip,Reason} | {comment,Comment} |
+%%               {save_config,Config1} | {skip_and_save,Reason,Config1}
+%% Config0 = Config1 = [tuple()]
+%% Reason = term()
+%% Comment = term()
+%%--------------------------------------------------------------------
+lib_type_register(_Config) ->
+  ok = dubbo_service_app:register_type_list(),
+  ok.
\ No newline at end of file
diff --git a/test/dubbo_service.hrl b/test/dubbo_service.hrl
new file mode 100644
index 0000000..e8a01e9
--- /dev/null
+++ b/test/dubbo_service.hrl
@@ -0,0 +1,14 @@
+
+-record(userInfoRequest,{
+    username ::list(),
+    requestId ::list()}).
+
+
+-record(userInfo,{
+    userName ::list(),
+    userId ::list(),
+    userAge ::integer()}).
+
+-record(userRes,{
+    userlist ::[]}).
+
diff --git a/test/dubbo_service_app.erl b/test/dubbo_service_app.erl
new file mode 100644
index 0000000..fdd839c
--- /dev/null
+++ b/test/dubbo_service_app.erl
@@ -0,0 +1,40 @@
+%%%-------------------------------------------------------------------
+%% @doc dubbo_service public API
+%% @end
+%%%-------------------------------------------------------------------
+
+-module(dubbo_service_app).
+
+-behaviour(application).
+
+%% Application callbacks
+-export([start/2, stop/1]).
+-export([register_type_list/0]).
+
+-include("dubbo_service.hrl").
+
+
+%%====================================================================
+%% API
+%%====================================================================
+
+start(_StartType, _StartArgs) ->
+    register_type_list(),
+    dubbo_service_sup:start_link().
+
+%%--------------------------------------------------------------------
+stop(_State) ->
+    ok.
+
+%%====================================================================
+%% Internal functions
+%%====================================================================
+
+
+register_type_list()->
+    List = dubbo_service_type_list:get_list(),
+    lists:map(
+        fun({NativeType,ForeignType,Fields}) ->
+        de_type_transfer:pre_process_typedef(NativeType,ForeignType,Fields)
+    end,List),
+    ok.
\ No newline at end of file
diff --git a/test/dubbo_service_type_list.erl b/test/dubbo_service_type_list.erl
new file mode 100644
index 0000000..1f01868
--- /dev/null
+++ b/test/dubbo_service_type_list.erl
@@ -0,0 +1,15 @@
+-module(dubbo_service_type_list).
+
+%% API
+-export([register_type_list/0,get_list/0]).
+
+-include("dubbo_service.hrl").
+
+get_list()->
+    [
+        {userInfoRequest,<<"com.ifcoder.demo.bean.UserInfoRequest">>,record_info(fields,userInfoRequest)},
+        {userInfo,<<"com.ifcoder.demo.bean.UserInfo">>,record_info(fields,userInfo)},
+        {userRes,<<"com.ifcoder.demo.bean.UserRes">>,record_info(fields,userRes)}    ].
+
+register_type_list()->
+    ok.
\ No newline at end of file
diff --git a/test/user.erl b/test/user.erl
new file mode 100644
index 0000000..4f905f1
--- /dev/null
+++ b/test/user.erl
@@ -0,0 +1,190 @@
+-module(user).
+
+-include_lib("dubboerl/include/dubbo.hrl").
+-include_lib("dubboerl/include/hessian.hrl").
+
+-define(CURRENT_CLASS_NAME,<<"com.ifcoder.demo.facade.User"/utf8>>).
+-define(CURRENT_CLASS_VERSION,<<"0.0.0"/utf8>>).
+
+-include("dubbo_service.hrl").
+
+
+
+
+%% API
+-export([
+    getUserInfo/1,
+    getUserInfo/2,
+    genUserId/0,
+    genUserId/1,
+    queryUserInfo/1,
+    queryUserInfo/2,
+    queryUserList/1,
+    queryUserList/2]).
+
+-export([get_method_999_list/0]).
+
+%% behaviour
+-callback getUserInfo(Arg0::list())-> #userInfo{}.
+-callback genUserId()-> list().
+-callback queryUserInfo(Arg0::#userInfoRequest{})-> #userInfo{}.
+-callback queryUserList(Arg0::list())-> #userRes{}.
+
+get_method_999_list()->
+    [
+    getUserInfo,
+    genUserId,
+    queryUserInfo,
+    queryUserList].
+
+
+
+-spec getUserInfo(Arg0::list())->
+    {ok,reference()}|
+    {ok,reference(),Data::#userInfo{},RpcContent::list()}|
+    {error,Reason::timeout|no_provider|any()}.
+getUserInfo(Arg0)->
+    getUserInfo(Arg0 ,[]).
+
+getUserInfo(Arg0, Option)->
+    
+    Data = #dubbo_rpc_invocation{
+        className = ?CURRENT_CLASS_NAME,
+        classVersion = ?CURRENT_CLASS_VERSION,
+        methodName = <<"getUserInfo">>,
+        parameterDesc = <<"Ljava/lang/String;"/utf8>>,
+        parameterTypes = [
+            #type_def{foreign_type = <<"java.lang.String">>,
+            native_type = string,
+            fieldnames = []}
+        ],
+        parameters = [
+            Arg0
+        ],
+        attachments = [
+            {<<"path">>, ?CURRENT_CLASS_NAME},
+            {<<"interface">> , ?CURRENT_CLASS_NAME}
+        ]
+    },
+    Request = #dubbo_request{
+        is_event = false,
+        is_twoway = true,
+        mid = de_id_count:gen_id(),
+        data = Data,
+        mversion= <<"0.0.0">>,
+        serialize_type = ?SERIALIZATION_HESSIAN
+    },
+    dubbo_invoker:invoke_request(?CURRENT_CLASS_NAME,Request).
+
+
+-spec genUserId()->
+    {ok,reference()}|
+    {ok,reference(),Data::list(),RpcContent::list()}|
+    {error,Reason::timeout|no_provider|any()}.
+genUserId()->
+    genUserId( []).
+
+genUserId( Option)->
+    
+    Data = #dubbo_rpc_invocation{
+        className = ?CURRENT_CLASS_NAME,
+        classVersion = ?CURRENT_CLASS_VERSION,
+        methodName = <<"genUserId">>,
+        parameterDesc = <<""/utf8>>,
+        parameterTypes = [
+            
+        ],
+        parameters = [
+            
+        ],
+        attachments = [
+            {<<"path">>, ?CURRENT_CLASS_NAME},
+            {<<"interface">> , ?CURRENT_CLASS_NAME}
+        ]
+    },
+    Request = #dubbo_request{
+        is_event = false,
+        is_twoway = true,
+        mid = de_id_count:gen_id(),
+        data = Data,
+        mversion= <<"0.0.0">>,
+        serialize_type = ?SERIALIZATION_HESSIAN
+    },
+    dubbo_invoker:invoke_request(?CURRENT_CLASS_NAME,Request).
+
+
+-spec queryUserInfo(Arg0::#userInfoRequest{})->
+    {ok,reference()}|
+    {ok,reference(),Data::#userInfo{},RpcContent::list()}|
+    {error,Reason::timeout|no_provider|any()}.
+queryUserInfo(Arg0)->
+    queryUserInfo(Arg0 ,[]).
+
+queryUserInfo(Arg0, Option)->
+    
+    Data = #dubbo_rpc_invocation{
+        className = ?CURRENT_CLASS_NAME,
+        classVersion = ?CURRENT_CLASS_VERSION,
+        methodName = <<"queryUserInfo">>,
+        parameterDesc = <<"Lcom/ifcoder/demo/bean/UserInfoRequest;"/utf8>>,
+        parameterTypes = [
+            #type_def{foreign_type = <<"com.ifcoder.demo.bean.UserInfoRequest">>,
+            native_type = userInfoRequest,
+            fieldnames = record_info(fields,userInfoRequest)}
+        ],
+        parameters = [
+            Arg0
+        ],
+        attachments = [
+            {<<"path">>, ?CURRENT_CLASS_NAME},
+            {<<"interface">> , ?CURRENT_CLASS_NAME}
+        ]
+    },
+    Request = #dubbo_request{
+        is_event = false,
+        is_twoway = true,
+        mid = de_id_count:gen_id(),
+        data = Data,
+        mversion= <<"0.0.0">>,
+        serialize_type = ?SERIALIZATION_HESSIAN
+    },
+    dubbo_invoker:invoke_request(?CURRENT_CLASS_NAME,Request).
+
+
+-spec queryUserList(Arg0::list())->
+    {ok,reference()}|
+    {ok,reference(),Data::#userRes{},RpcContent::list()}|
+    {error,Reason::timeout|no_provider|any()}.
+queryUserList(Arg0)->
+    queryUserList(Arg0 ,[]).
+
+queryUserList(Arg0, Option)->
+    
+    Data = #dubbo_rpc_invocation{
+        className = ?CURRENT_CLASS_NAME,
+        classVersion = ?CURRENT_CLASS_VERSION,
+        methodName = <<"queryUserList">>,
+        parameterDesc = <<"Ljava/lang/String;"/utf8>>,
+        parameterTypes = [
+            #type_def{foreign_type = <<"java.lang.String">>,
+            native_type = string,
+            fieldnames = []}
+        ],
+        parameters = [
+            Arg0
+        ],
+        attachments = [
+            {<<"path">>, ?CURRENT_CLASS_NAME},
+            {<<"interface">> , ?CURRENT_CLASS_NAME}
+        ]
+    },
+    Request = #dubbo_request{
+        is_event = false,
+        is_twoway = true,
+        mid = de_id_count:gen_id(),
+        data = Data,
+        mversion= <<"0.0.0">>,
+        serialize_type = ?SERIALIZATION_HESSIAN
+    },
+    dubbo_invoker:invoke_request(?CURRENT_CLASS_NAME,Request).
+