test(emqx_lwm2m): remove the lwm2m_coap dependency

This commit is contained in:
lafirest 2021-09-13 18:34:54 +08:00
parent 86eb6605f1
commit acbbbbcd24
4 changed files with 52 additions and 152 deletions

View File

@ -1,6 +1,5 @@
{erl_opts, [debug_info]}. {erl_opts, [debug_info]}.
{deps, [ {deps, [
{lwm2m_coap, {git, "https://github.com/emqx/lwm2m-coap", {tag, "v2.0.0"}}},
{grpc, {git, "https://github.com/emqx/grpc-erl", {tag, "0.6.2"}}} {grpc, {git, "https://github.com/emqx/grpc-erl", {tag, "0.6.2"}}}
]}. ]}.

View File

@ -3,7 +3,7 @@
{vsn, "0.1.0"}, {vsn, "0.1.0"},
{registered, []}, {registered, []},
{mod, {emqx_gateway_app, []}}, {mod, {emqx_gateway_app, []}},
{applications, [kernel, stdlib, grpc, lwm2m_coap, emqx]}, {applications, [kernel, stdlib, grpc, emqx]},
{env, []}, {env, []},
{modules, []}, {modules, []},
{licenses, ["Apache 2.0"]}, {licenses, ["Apache 2.0"]},

View File

@ -24,7 +24,7 @@
-define(LOGT(Format, Args), ct:pal("TEST_SUITE: " ++ Format, Args)). -define(LOGT(Format, Args), ct:pal("TEST_SUITE: " ++ Format, Args)).
-include_lib("emqx_gateway/src/lwm2m/include/emqx_lwm2m.hrl"). -include_lib("emqx_gateway/src/lwm2m/include/emqx_lwm2m.hrl").
-include_lib("lwm2m_coap/include/coap.hrl"). -include_lib("emqx_gateway/src/coap/include/emqx_coap.hrl").
-include_lib("eunit/include/eunit.hrl"). -include_lib("eunit/include/eunit.hrl").
-include_lib("common_test/include/ct.hrl"). -include_lib("common_test/include/ct.hrl").
@ -50,6 +50,8 @@ gateway.lwm2m {
} }
">>). ">>).
-record(coap_content, {content_format, payload = <<>>}).
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
%% Setups %% Setups
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
@ -199,7 +201,7 @@ case01_register(Config) ->
ack = Type, ack = Type,
{ok, created} = Method, {ok, created} = Method,
RspId = MsgId, RspId = MsgId,
Location = proplists:get_value(location_path, Opts), Location = maps:get(location_path, Opts),
?assertNotEqual(undefined, Location), ?assertNotEqual(undefined, Location),
%% checkpoint 2 - verify subscribed topics %% checkpoint 2 - verify subscribed topics
@ -247,7 +249,7 @@ case01_register_additional_opts(Config) ->
Type = ack, Type = ack,
Method = {ok, created}, Method = {ok, created},
RspId = MsgId, RspId = MsgId,
Location = proplists:get_value(location_path, Opts), Location = maps:get(location_path, Opts),
?assertNotEqual(undefined, Location), ?assertNotEqual(undefined, Location),
%% checkpoint 2 - verify subscribed topics %% checkpoint 2 - verify subscribed topics
@ -318,7 +320,7 @@ case01_register_report(Config) ->
Type = ack, Type = ack,
Method = {ok, created}, Method = {ok, created},
RspId = MsgId, RspId = MsgId,
Location = proplists:get_value(location_path, Opts), Location = maps:get(location_path, Opts),
?assertNotEqual(undefined, Location), ?assertNotEqual(undefined, Location),
timer:sleep(50), timer:sleep(50),
@ -376,7 +378,7 @@ case02_update_deregister(Config) ->
?assertEqual({ok,created}, Method), ?assertEqual({ok,created}, Method),
?LOGT("Options got: ~p", [Opts]), ?LOGT("Options got: ~p", [Opts]),
Location = proplists:get_value(location_path, Opts), Location = maps:get(location_path, Opts),
Register = emqx_json:encode(#{ Register = emqx_json:encode(#{
<<"msgType">> => <<"register">>, <<"msgType">> => <<"register">>,
<<"data">> => #{ <<"data">> => #{
@ -1334,7 +1336,7 @@ case31_execute_error(Config) ->
?assertEqual(<<"2,7">>, Payload2), ?assertEqual(<<"2,7">>, Payload2),
timer:sleep(50), timer:sleep(50),
test_send_coap_response(UdpSock, "127.0.0.1", ?PORT, {error, uauthorized}, #coap_content{}, Request2, true), test_send_coap_response(UdpSock, "127.0.0.1", ?PORT, {error, unauthorized}, #coap_content{}, Request2, true),
timer:sleep(100), timer:sleep(100),
ReadResult = emqx_json:encode(#{ ReadResult = emqx_json:encode(#{
@ -1432,10 +1434,10 @@ case50_write_attribute(Config) ->
#coap_message{method = Method2, options=Options2, payload=Payload2} = Request2, #coap_message{method = Method2, options=Options2, payload=Payload2} = Request2,
?LOGT("got options: ~p", [Options2]), ?LOGT("got options: ~p", [Options2]),
Path2 = get_coap_path(Options2), Path2 = get_coap_path(Options2),
Query2 = lists:sort(get_coap_query(Options2)), Query2 = lists:sort(maps:to_list(get_coap_query(Options2))),
?assertEqual(put, Method2), ?assertEqual(put, Method2),
?assertEqual(<<"/3/0/9">>, Path2), ?assertEqual(<<"/3/0/9">>, Path2),
?assertEqual(lists:sort([<<"pmax=5">>,<<"lt=5">>,<<"pmin=1">>]), Query2), ?assertEqual(lists:sort([{<<"pmax">>, <<"5">>},{<<"lt">>, <<"5">>},{<<"pmin">>,<<"1">>}]), Query2),
?assertEqual(<<>>, Payload2), ?assertEqual(<<>>, Payload2),
timer:sleep(50), timer:sleep(50),
@ -1742,7 +1744,7 @@ server_cache_mode(Config, RegOption) ->
#coap_message{type = ack, method = Method1, options = Opts} = test_recv_coap_response(UdpSock), #coap_message{type = ack, method = Method1, options = Opts} = test_recv_coap_response(UdpSock),
?assertEqual({ok,created}, Method1), ?assertEqual({ok,created}, Method1),
?LOGT("Options got: ~p", [Opts]), ?LOGT("Options got: ~p", [Opts]),
Location = proplists:get_value(location_path, Opts), Location = maps:get(location_path, Opts),
test_recv_mqtt_response(RespTopic), test_recv_mqtt_response(RespTopic),
%% server not in PSM mode %% server not in PSM mode
@ -1836,10 +1838,10 @@ test_send_coap_request(UdpSock, Method, Uri, Content, Options, MsgId) ->
is_list(Options) orelse error("Options must be a list"), is_list(Options) orelse error("Options must be a list"),
case resolve_uri(Uri) of case resolve_uri(Uri) of
{coap, {IpAddr, Port}, Path, Query} -> {coap, {IpAddr, Port}, Path, Query} ->
Request0 = lwm2m_coap_message:request(con, Method, Content, [{uri_path, Path}, {uri_query, Query} | Options]), Request0 = request(con, Method, Content, [{uri_path, Path}, {uri_query, Query} | Options]),
Request = Request0#coap_message{id = MsgId}, Request = Request0#coap_message{id = MsgId},
?LOGT("send_coap_request Request=~p", [Request]), ?LOGT("send_coap_request Request=~p", [Request]),
RequestBinary = lwm2m_coap_message_parser:encode(Request), RequestBinary = emqx_coap_frame:serialize_pkt(Request, undefined),
?LOGT("test udp socket send to ~p:~p, data=~p", [IpAddr, Port, RequestBinary]), ?LOGT("test udp socket send to ~p:~p, data=~p", [IpAddr, Port, RequestBinary]),
ok = gen_udp:send(UdpSock, IpAddr, Port, RequestBinary); ok = gen_udp:send(UdpSock, IpAddr, Port, RequestBinary);
{SchemeDiff, ChIdDiff, _, _} -> {SchemeDiff, ChIdDiff, _, _} ->
@ -1848,7 +1850,7 @@ test_send_coap_request(UdpSock, Method, Uri, Content, Options, MsgId) ->
test_recv_coap_response(UdpSock) -> test_recv_coap_response(UdpSock) ->
{ok, {Address, Port, Packet}} = gen_udp:recv(UdpSock, 0, 2000), {ok, {Address, Port, Packet}} = gen_udp:recv(UdpSock, 0, 2000),
Response = lwm2m_coap_message_parser:decode(Packet), {ok, Response, _, _} = emqx_coap_frame:parse(Packet, undefined),
?LOGT("test udp receive from ~p:~p, data1=~p, Response=~p", [Address, Port, Packet, Response]), ?LOGT("test udp receive from ~p:~p, data1=~p, Response=~p", [Address, Port, Packet, Response]),
#coap_message{type = ack, method = Method, id=Id, token = Token, options = Options, payload = Payload} = Response, #coap_message{type = ack, method = Method, id=Id, token = Token, options = Options, payload = Payload} = Response,
?LOGT("receive coap response Method=~p, Id=~p, Token=~p, Options=~p, Payload=~p", [Method, Id, Token, Options, Payload]), ?LOGT("receive coap response Method=~p, Id=~p, Token=~p, Options=~p, Payload=~p", [Method, Id, Token, Options, Payload]),
@ -1857,7 +1859,7 @@ test_recv_coap_response(UdpSock) ->
test_recv_coap_request(UdpSock) -> test_recv_coap_request(UdpSock) ->
case gen_udp:recv(UdpSock, 0, 2000) of case gen_udp:recv(UdpSock, 0, 2000) of
{ok, {_Address, _Port, Packet}} -> {ok, {_Address, _Port, Packet}} ->
Request = lwm2m_coap_message_parser:decode(Packet), {ok, Request, _, _} = emqx_coap_frame:parse(Packet, undefined),
#coap_message{type = con, method = Method, id=Id, token = Token, payload = Payload, options = Options} = Request, #coap_message{type = con, method = Method, id=Id, token = Token, payload = Payload, options = Options} = Request,
?LOGT("receive coap request Method=~p, Id=~p, Token=~p, Options=~p, Payload=~p", [Method, Id, Token, Options, Payload]), ?LOGT("receive coap request Method=~p, Id=~p, Token=~p, Options=~p, Payload=~p", [Method, Id, Token, Options, Payload]),
Request; Request;
@ -1871,32 +1873,32 @@ test_send_coap_response(UdpSock, Host, Port, Code, Content, Request, Ack) ->
is_list(Host) orelse error("Host is not a string"), is_list(Host) orelse error("Host is not a string"),
{ok, IpAddr} = inet:getaddr(Host, inet), {ok, IpAddr} = inet:getaddr(Host, inet),
Response = lwm2m_coap_message:response(Code, Content, Request), Response = response(Code, Content, Request),
Response2 = case Ack of Response2 = case Ack of
true -> Response#coap_message{type = ack}; true -> Response#coap_message{type = ack};
false -> Response false -> Response
end, end,
?LOGT("test_send_coap_response Response=~p", [Response2]), ?LOGT("test_send_coap_response Response=~p", [Response2]),
ok = gen_udp:send(UdpSock, IpAddr, Port, lwm2m_coap_message_parser:encode(Response2)). ok = gen_udp:send(UdpSock, IpAddr, Port, emqx_coap_frame:serialize_pkt(Response2, undefined)).
test_send_empty_ack(UdpSock, Host, Port, Request) -> test_send_empty_ack(UdpSock, Host, Port, Request) ->
is_list(Host) orelse error("Host is not a string"), is_list(Host) orelse error("Host is not a string"),
{ok, IpAddr} = inet:getaddr(Host, inet), {ok, IpAddr} = inet:getaddr(Host, inet),
EmptyACK = lwm2m_coap_message:ack(Request), EmptyACK = emqx_coap_message:ack(Request),
?LOGT("test_send_empty_ack EmptyACK=~p", [EmptyACK]), ?LOGT("test_send_empty_ack EmptyACK=~p", [EmptyACK]),
ok = gen_udp:send(UdpSock, IpAddr, Port, lwm2m_coap_message_parser:encode(EmptyACK)). ok = gen_udp:send(UdpSock, IpAddr, Port, emqx_coap_frame:serialize_pkt(EmptyACK, undefined)).
test_send_coap_observe_ack(UdpSock, Host, Port, Code, Content, Request) -> test_send_coap_observe_ack(UdpSock, Host, Port, Code, Content, Request) ->
is_record(Content, coap_content) orelse error("Content must be a #coap_content!"), is_record(Content, coap_content) orelse error("Content must be a #coap_content!"),
is_list(Host) orelse error("Host is not a string"), is_list(Host) orelse error("Host is not a string"),
{ok, IpAddr} = inet:getaddr(Host, inet), {ok, IpAddr} = inet:getaddr(Host, inet),
Response = lwm2m_coap_message:response(Code, Content, Request), Response = response(Code, Content, Request),
Response1 = lwm2m_coap_message:set(observe, 0, Response), Response1 = emqx_coap_message:set(observe, 0, Response),
Response2 = Response1#coap_message{type = ack}, Response2 = Response1#coap_message{type = ack},
?LOGT("test_send_coap_observe_ack Response=~p", [Response2]), ?LOGT("test_send_coap_observe_ack Response=~p", [Response2]),
ResponseBinary = lwm2m_coap_message_parser:encode(Response2), ResponseBinary = emqx_coap_frame:serialize_pkt(Response2, undefined),
ok = gen_udp:send(UdpSock, IpAddr, Port, ResponseBinary). ok = gen_udp:send(UdpSock, IpAddr, Port, ResponseBinary).
test_send_coap_notif(UdpSock, Host, Port, Content, ObSeq, Request) -> test_send_coap_notif(UdpSock, Host, Port, Content, ObSeq, Request) ->
@ -1904,10 +1906,10 @@ test_send_coap_notif(UdpSock, Host, Port, Content, ObSeq, Request) ->
is_list(Host) orelse error("Host is not a string"), is_list(Host) orelse error("Host is not a string"),
{ok, IpAddr} = inet:getaddr(Host, inet), {ok, IpAddr} = inet:getaddr(Host, inet),
Notif = lwm2m_coap_message:response({ok, content}, Content, Request), Notif = response({ok, content}, Content, Request),
NewNotif = lwm2m_coap_message:set(observe, ObSeq, Notif), NewNotif = emqx_coap_message:set(observe, ObSeq, Notif),
?LOGT("test_send_coap_notif Response=~p", [NewNotif]), ?LOGT("test_send_coap_notif Response=~p", [NewNotif]),
NotifBinary = lwm2m_coap_message_parser:encode(NewNotif), NotifBinary = emqx_coap_frame:serialize_pkt(NewNotif, undefined),
?LOGT("test udp socket send to ~p:~p, data=~p", [IpAddr, Port, NotifBinary]), ?LOGT("test udp socket send to ~p:~p, data=~p", [IpAddr, Port, NotifBinary]),
ok = gen_udp:send(UdpSock, IpAddr, Port, NotifBinary). ok = gen_udp:send(UdpSock, IpAddr, Port, NotifBinary).
@ -1952,30 +1954,18 @@ make_segment(Seg) ->
get_coap_path(Options) -> get_coap_path(Options) ->
get_path(Options, <<>>). Seps = maps:get(uri_path, Options, []),
lists:foldl(fun(Sep, Acc) ->
<<Acc/binary, $/, Sep/binary>>
end,
<<>>,
Seps).
get_coap_query(Options) -> get_coap_query(Options) ->
proplists:get_value(uri_query, Options, []). maps:get(uri_query, Options, #{}).
get_coap_observe(Options) -> get_coap_observe(Options) ->
get_observe(Options). maps:get(observe, Options, undefined).
get_path([], Acc) ->
%?LOGT("get_path Acc=~p", [Acc]),
Acc;
get_path([{uri_path, Path1}|T], Acc) ->
%?LOGT("Path=~p, Acc=~p", [Path1, Acc]),
get_path(T, join_path(Path1, Acc));
get_path([{_, _}|T], Acc) ->
get_path(T, Acc).
get_observe([]) ->
undefined;
get_observe([{observe, V}|_T]) ->
V;
get_observe([{_, _}|T]) ->
get_observe(T).
join_path([], Acc) -> Acc; join_path([], Acc) -> Acc;
join_path([<<"/">>|T], Acc) -> join_path([<<"/">>|T], Acc) ->
@ -1985,3 +1975,10 @@ join_path([H|T], Acc) ->
sprintf(Format, Args) -> sprintf(Format, Args) ->
lists:flatten(io_lib:format(Format, Args)). lists:flatten(io_lib:format(Format, Args)).
response(Code, #coap_content{content_format = Format, payload = Payload}, Req) ->
#coap_message{options = Opts} = Msg = emqx_coap_message:response(Code, Payload, Req),
Msg#coap_message{options = Opts#{content_format => Format}}.
request(Type, Method, #coap_content{content_format = Format, payload = Payload}, Opts) ->
emqx_coap_message:request(Type, Method, Payload, [{content_format, Format} | Opts]).

View File

@ -24,7 +24,7 @@
-define(LOGT(Format, Args), ct:pal("TEST_SUITE: " ++ Format, Args)). -define(LOGT(Format, Args), ct:pal("TEST_SUITE: " ++ Format, Args)).
-include_lib("emqx_gateway/src/lwm2m/include/emqx_lwm2m.hrl"). -include_lib("emqx_gateway/src/lwm2m/include/emqx_lwm2m.hrl").
-include_lib("lwm2m_coap/include/coap.hrl"). -include_lib("emqx_gateway/src/coap/include/emqx_coap.hrl").
-include_lib("eunit/include/eunit.hrl"). -include_lib("eunit/include/eunit.hrl").
-include_lib("common_test/include/ct.hrl"). -include_lib("common_test/include/ct.hrl").
@ -53,6 +53,14 @@ gateway.lwm2m {
-define(assertExists(Map, Key), -define(assertExists(Map, Key),
?assertNotEqual(maps:get(Key, Map, undefined), undefined)). ?assertNotEqual(maps:get(Key, Map, undefined), undefined)).
-record(coap_content, {content_format, payload = <<>>}).
-import(emqx_lwm2m_SUITE, [ request/4, response/3, test_send_coap_response/7
, test_recv_coap_request/1, test_recv_coap_response/1
, test_send_coap_request/6, test_recv_mqtt_response/1
, std_register/5, reslove_uri/1, split_path/1, split_query/1
, join_path/2, sprintf/2]).
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
%% Setups %% Setups
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
@ -214,107 +222,3 @@ discover_received_request(ClientId, Path, Action) ->
?assertExists(Res, <<"path">>), ?assertExists(Res, <<"path">>),
?assertExists(Res, <<"name">>), ?assertExists(Res, <<"name">>),
?assertExists(Res, <<"operations">>). ?assertExists(Res, <<"operations">>).
test_recv_mqtt_response(RespTopic) ->
receive
{publish, #{topic := RespTopic, payload := RM}} ->
?LOGT("test_recv_mqtt_response Response=~p", [RM]),
RM
after 1000 -> timeout_test_recv_mqtt_response
end.
test_send_coap_request(UdpSock, Method, Uri, Content, Options, MsgId) ->
is_record(Content, coap_content) orelse error("Content must be a #coap_content!"),
is_list(Options) orelse error("Options must be a list"),
case resolve_uri(Uri) of
{coap, {IpAddr, Port}, Path, Query} ->
Request0 = lwm2m_coap_message:request(con, Method, Content, [{uri_path, Path}, {uri_query, Query} | Options]),
Request = Request0#coap_message{id = MsgId},
?LOGT("send_coap_request Request=~p", [Request]),
RequestBinary = lwm2m_coap_message_parser:encode(Request),
?LOGT("test udp socket send to ~p:~p, data=~p", [IpAddr, Port, RequestBinary]),
ok = gen_udp:send(UdpSock, IpAddr, Port, RequestBinary);
{SchemeDiff, ChIdDiff, _, _} ->
error(lists:flatten(io_lib:format("scheme ~s or ChId ~s does not match with socket", [SchemeDiff, ChIdDiff])))
end.
test_recv_coap_response(UdpSock) ->
{ok, {Address, Port, Packet}} = gen_udp:recv(UdpSock, 0, 2000),
Response = lwm2m_coap_message_parser:decode(Packet),
?LOGT("test udp receive from ~p:~p, data1=~p, Response=~p", [Address, Port, Packet, Response]),
#coap_message{type = ack, method = Method, id=Id, token = Token, options = Options, payload = Payload} = Response,
?LOGT("receive coap response Method=~p, Id=~p, Token=~p, Options=~p, Payload=~p", [Method, Id, Token, Options, Payload]),
Response.
test_recv_coap_request(UdpSock) ->
case gen_udp:recv(UdpSock, 0, 2000) of
{ok, {_Address, _Port, Packet}} ->
Request = lwm2m_coap_message_parser:decode(Packet),
#coap_message{type = con, method = Method, id=Id, token = Token, payload = Payload, options = Options} = Request,
?LOGT("receive coap request Method=~p, Id=~p, Token=~p, Options=~p, Payload=~p", [Method, Id, Token, Options, Payload]),
Request;
{error, Reason} ->
?LOGT("test_recv_coap_request failed, Reason=~p", [Reason]),
timeout_test_recv_coap_request
end.
test_send_coap_response(UdpSock, Host, Port, Code, Content, Request, Ack) ->
is_record(Content, coap_content) orelse error("Content must be a #coap_content!"),
is_list(Host) orelse error("Host is not a string"),
{ok, IpAddr} = inet:getaddr(Host, inet),
Response = lwm2m_coap_message:response(Code, Content, Request),
Response2 = case Ack of
true -> Response#coap_message{type = ack};
false -> Response
end,
?LOGT("test_send_coap_response Response=~p", [Response2]),
ok = gen_udp:send(UdpSock, IpAddr, Port, lwm2m_coap_message_parser:encode(Response2)).
std_register(UdpSock, Epn, ObjectList, MsgId1, RespTopic) ->
test_send_coap_request( UdpSock,
post,
sprintf("coap://127.0.0.1:~b/rd?ep=~s&lt=345&lwm2m=1", [?PORT, Epn]),
#coap_content{content_format = <<"text/plain">>, payload = ObjectList},
[],
MsgId1),
#coap_message{method = {ok,created}} = test_recv_coap_response(UdpSock),
test_recv_mqtt_response(RespTopic),
timer:sleep(100).
resolve_uri(Uri) ->
{ok, #{scheme := Scheme,
host := Host,
port := PortNo,
path := Path} = URIMap} = emqx_http_lib:uri_parse(Uri),
Query = maps:get(query, URIMap, ""),
{ok, PeerIP} = inet:getaddr(Host, inet),
{Scheme, {PeerIP, PortNo}, split_path(Path), split_query(Query)}.
split_path([]) -> [];
split_path([$/]) -> [];
split_path([$/ | Path]) -> split_segments(Path, $/, []).
split_query([]) -> [];
split_query(Path) -> split_segments(Path, $&, []).
split_segments(Path, Char, Acc) ->
case string:rchr(Path, Char) of
0 ->
[make_segment(Path) | Acc];
N when N > 0 ->
split_segments(string:substr(Path, 1, N-1), Char,
[make_segment(string:substr(Path, N+1)) | Acc])
end.
make_segment(Seg) ->
list_to_binary(emqx_http_lib:uri_decode(Seg)).
join_path([], Acc) -> Acc;
join_path([<<"/">>|T], Acc) ->
join_path(T, Acc);
join_path([H|T], Acc) ->
join_path(T, <<Acc/binary, $/, H/binary>>).
sprintf(Format, Args) ->
lists:flatten(io_lib:format(Format, Args)).