aboutsummaryrefslogtreecommitdiffstats
path: root/lib/common_test/test
diff options
context:
space:
mode:
authorSiri Hansen <[email protected]>2016-02-12 15:04:30 +0100
committerSiri Hansen <[email protected]>2016-02-18 12:31:54 +0100
commit171d7e2a161ef9270240aff0fa15a285df21c1ef (patch)
treeddf78a4feebc8af23c27f311f8502bb50cc8f98a /lib/common_test/test
parentd96471b3f404f7341279d8598dd74d92fb1a923c (diff)
downloadotp-171d7e2a161ef9270240aff0fa15a285df21c1ef.tar.gz
otp-171d7e2a161ef9270240aff0fa15a285df21c1ef.tar.bz2
otp-171d7e2a161ef9270240aff0fa15a285df21c1ef.zip
[ct_netconfc] Fix XML parsing when multiple messages in package
If a ssh package contained more than one netconf end tag, then the second end tag was never detected in ct_netconfc:handle_data. Instead it was included in the XML data given to the xmerl parser, which then failed with reason "\"]]>\" is not allowed in content". This problem was introduced by OTP-13007.
Diffstat (limited to 'lib/common_test/test')
-rw-r--r--lib/common_test/test/ct_netconfc_SUITE_data/netconfc1_SUITE.erl194
-rw-r--r--lib/common_test/test/ct_netconfc_SUITE_data/ns.erl23
2 files changed, 203 insertions, 14 deletions
diff --git a/lib/common_test/test/ct_netconfc_SUITE_data/netconfc1_SUITE.erl b/lib/common_test/test/ct_netconfc_SUITE_data/netconfc1_SUITE.erl
index ea49e36608..49b02d2bba 100644
--- a/lib/common_test/test/ct_netconfc_SUITE_data/netconfc1_SUITE.erl
+++ b/lib/common_test/test/ct_netconfc_SUITE_data/netconfc1_SUITE.erl
@@ -99,7 +99,10 @@ all() ->
connection_crash,
get_event_streams,
create_subscription,
- receive_event
+ receive_one_event,
+ receive_multiple_events,
+ receive_event_and_rpc,
+ receive_event_and_rpc_in_chunks
]
end.
@@ -354,7 +357,7 @@ get(Config) ->
get_a_lot(Config) ->
DataDir = ?config(data_dir,Config),
{ok,Client} = open_success(DataDir),
- Descr = lists:append(lists:duplicate(100,"Description of myserver! ")),
+ Descr = lists:append(lists:duplicate(1000,"Description of myserver! ")),
Server = {server,[{xmlns,"myns"}],[{name,[],["myserver"]},
{description,[],[Descr]}]},
Data = lists:duplicate(100,Server),
@@ -964,16 +967,16 @@ create_subscription(Config) ->
ok.
-receive_event(Config) ->
+receive_one_event(Config) ->
DataDir = ?config(data_dir,Config),
{ok,Client} = open_success(DataDir),
?NS:expect_reply({'create-subscription',[stream]},ok),
?ok = ct_netconfc:create_subscription(Client),
- ?NS:hupp(send_event),
+ ?NS:hupp({send_events,1}),
receive
- %% Matching ?NS:make_msg(event)
+ %% Matching ?NS:make_msg({event,_})
{notification,?NETCONF_NOTIF_NAMESPACE_ATTR,
[{eventTime,[],[_Time]},
{event,[{xmlns,"http://my.namespaces.com/event"}],
@@ -991,6 +994,187 @@ receive_event(Config) ->
ok.
+receive_multiple_events(Config) ->
+ DataDir = ?config(data_dir,Config),
+ {ok,Client} = open_success(DataDir),
+ ?NS:expect_reply({'create-subscription',[stream]},ok),
+ ?ok = ct_netconfc:create_subscription(Client),
+
+ ?NS:hupp({send_events,3}),
+
+ receive
+ %% Matching ?NS:make_msg({event,_})
+ {notification,_,_} ->
+ ok;
+ Other1 ->
+ ct:fail({got_unexpected_while_waiting_for_event, Other1})
+ after 3000 ->
+ ct:fail(timeout_waiting_for_event)
+ end,
+ receive
+ %% Matching ?NS:make_msg({event,_})
+ {notification,_,_} ->
+ ok;
+ Other2 ->
+ ct:fail({got_unexpected_while_waiting_for_event, Other2})
+ after 3000 ->
+ ct:fail(timeout_waiting_for_event)
+ end,
+ receive
+ %% Matching ?NS:make_msg({event,_})
+ {notification,_,_} ->
+ ok;
+ Other3 ->
+ ct:fail({got_unexpected_while_waiting_for_event, Other3})
+ after 3000 ->
+ ct:fail(timeout_waiting_for_event)
+ end,
+
+ ?NS:expect_do_reply('close-session',close,ok),
+ ?ok = ct_netconfc:close_session(Client),
+
+ ok.
+
+receive_event_and_rpc(Config) ->
+ DataDir = ?config(data_dir,Config),
+ {ok,Client} = open_success(DataDir),
+
+ ?NS:expect_reply({'create-subscription',[stream]},ok),
+ ?ok = ct_netconfc:create_subscription(Client),
+
+ %% Construct the data to return from netconf server - one
+ %% rpc-reply and one notification - to be sent in the same ssh
+ %% package.
+ Data = [{servers,[{xmlns,"myns"}],[{server,[],[{name,[],["myserver"]}]}]}],
+ Rpc = {'rpc-reply',?NETCONF_NAMESPACE_ATTR ++ [{'message-id',"2"}],
+ [{data,Data}]},
+ RpcXml = list_to_binary(xmerl:export_simple_element(Rpc,xmerl_xml)),
+
+ Notification =
+ {notification,?NETCONF_NOTIF_NAMESPACE_ATTR,
+ [{eventTime,["2012-06-14T14:50:54+02:00"]},
+ {event,[{xmlns,"http://my.namespaces.com/event"}],
+ [{severity,["major"]},
+ {description,["Something terrible happened"]}]}]},
+ NotifXml =
+ list_to_binary(xmerl:export_simple_element(Notification,xmerl_xml)),
+
+ ?NS:expect_reply('get',[RpcXml,NotifXml]),
+ {ok,Data} = ct_netconfc:get(Client,{server,[{xmlns,"myns"}],[]}),
+
+ receive
+ {notification,_,_} ->
+ ok;
+ Other1 ->
+ ct:fail({got_unexpected_while_waiting_for_event, Other1})
+ after 3000 ->
+ ct:fail(timeout_waiting_for_event)
+ end,
+
+
+ %% Then do the same again, but now send notification first then
+ %% the rpc-reply.
+ Rpc2 = {'rpc-reply',?NETCONF_NAMESPACE_ATTR ++ [{'message-id',"3"}],
+ [{data,Data}]},
+ RpcXml2 = list_to_binary(xmerl:export_simple_element(Rpc2,xmerl_xml)),
+ ?NS:expect_reply('get',[NotifXml,RpcXml2]),
+ {ok,Data} = ct_netconfc:get(Client,{server,[{xmlns,"myns"}],[]}),
+
+ receive
+ {notification,_,_} ->
+ ok;
+ Other2 ->
+ ct:fail({got_unexpected_while_waiting_for_event, Other2})
+ after 3000 ->
+ ct:fail(timeout_waiting_for_event)
+ end,
+
+ ?NS:expect_do_reply('close-session',close,ok),
+ ?ok = ct_netconfc:close_session(Client),
+
+ ok.
+
+
+receive_event_and_rpc_in_chunks(Config) ->
+ DataDir = ?config(data_dir,Config),
+ {ok,Client} = open_success(DataDir),
+
+ ?NS:expect_reply({'create-subscription',[stream]},ok),
+ ?ok = ct_netconfc:create_subscription(Client),
+
+ %% Construct the data to return from netconf server
+ Data = [{servers,[{xmlns,"myns"}],
+ [{server,[],[{name,[],["server0"]}]},
+ {server,[],[{name,[],["server1"]}]},
+ {server,[],[{name,[],["server2"]}]},
+ {server,[],[{name,[],["server3"]}]},
+ {server,[],[{name,[],["server4"]}]},
+ {server,[],[{name,[],["server5"]}]},
+ {server,[],[{name,[],["server6"]}]},
+ {server,[],[{name,[],["server7"]}]},
+ {server,[],[{name,[],["server8"]}]},
+ {server,[],[{name,[],["server9"]}]}]
+ }],
+ Rpc = {'rpc-reply',?NETCONF_NAMESPACE_ATTR ++ [{'message-id',"2"}],
+ [{data,Data}]},
+ RpcXml = list_to_binary(xmerl:export_simple_element(Rpc,xmerl_xml)),
+
+ Notification =
+ {notification,?NETCONF_NOTIF_NAMESPACE_ATTR,
+ [{eventTime,["2012-06-14T14:50:54+02:00"]},
+ {event,[{xmlns,"http://my.namespaces.com/event"}],
+ [{severity,["major"]},
+ {description,["Something terrible happened"]}]}]},
+ NotifXml =
+ list_to_binary(xmerl:export_simple_element(Notification,xmerl_xml)),
+
+
+ %% First part contains a notif, but only parts of the end tag
+ Part1 =
+ <<"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",
+ NotifXml/binary,"\n]]">>,
+
+ %% Second part contains rest of end tag, full rpc-reply and full
+ %% notif except end tag
+ Part2 =
+ <<">]]>\n",RpcXml/binary,"\n",?END_TAG/binary,NotifXml/binary>>,
+
+ %% Third part contains last end tag
+ Part3 = <<"\n",?END_TAG/binary,"\n">>,
+
+ %% Spawn a process which will wait a bit for the client to send
+ %% the request (below), then order the server to the chunks of the
+ %% rpc-reply one by one.
+ spawn(fun() -> ct:sleep(500),?NS:hupp(send,Part1),
+ ct:sleep(100),?NS:hupp(send,Part2),
+ ct:sleep(100),?NS:hupp(send,Part3)
+ end),
+
+ %% Order server to expect a get - then the process above will make
+ %% sure the rpc-reply is sent.
+ ?NS:expect('get'),
+ {ok,Data} = ct_netconfc:get(Client,{server,[{xmlns,"myns"}],[]}),
+
+ receive
+ {notification,_,_} ->
+ ok;
+ Other1 ->
+ ct:fail({got_unexpected_while_waiting_for_event, Other1})
+ after 3000 ->
+ ct:fail(timeout_waiting_for_event)
+ end,
+ receive
+ {notification,_,_} ->
+ ok;
+ Other2 ->
+ ct:fail({got_unexpected_while_waiting_for_event, Other2})
+ after 3000 ->
+ ct:fail(timeout_waiting_for_event)
+ end,
+ ?NS:expect_do_reply('close-session',close,ok),
+ ?ok = ct_netconfc:close_session(Client),
+ ok.
+
%%%-----------------------------------------------------------------
break(_Config) ->
diff --git a/lib/common_test/test/ct_netconfc_SUITE_data/ns.erl b/lib/common_test/test/ct_netconfc_SUITE_data/ns.erl
index 07893faabc..67827a053f 100644
--- a/lib/common_test/test/ct_netconfc_SUITE_data/ns.erl
+++ b/lib/common_test/test/ct_netconfc_SUITE_data/ns.erl
@@ -144,8 +144,8 @@ expect_do_reply(SessionId,Expect,Do,Reply) ->
%% Hupp the server - i.e. tell it to do something -
%% e.g. hupp(send_event) will cause send_event(State) to be called on
%% the session channel process.
-hupp(send_event) ->
- hupp(send,[make_msg(event)]);
+hupp({send_events,N}) ->
+ hupp(send,[make_msg({event,N})]);
hupp(kill) ->
hupp(1,fun hupp_kill/1,[]).
@@ -446,9 +446,12 @@ reply(ConnRef,Reply) ->
from_simple(Simple) ->
unicode_c2b(xmerl:export_simple_element(Simple,xmerl_xml)).
-xml(Content) ->
- <<"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",
- Content/binary,"\n",?END_TAG/binary>>.
+xml(Content) when is_binary(Content) ->
+ xml([Content]);
+xml(Content) when is_list(Content) ->
+ Msgs = [<<Msg/binary,"\n",?END_TAG/binary>> || Msg <- Content],
+ MsgsBin = list_to_binary(Msgs),
+ <<"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", MsgsBin/binary>>.
rpc_reply(Content) when is_binary(Content) ->
MsgId = case erase(msg_id) of
@@ -571,15 +574,17 @@ make_msg({ok,Data}) ->
make_msg({data,Data}) ->
xml(rpc_reply(from_simple({data,Data})));
-make_msg(event) ->
- xml(<<"<notification xmlns=\"",?NETCONF_NOTIF_NAMESPACE,"\">"
+make_msg({event,N}) ->
+ Notification = <<"<notification xmlns=\"",?NETCONF_NOTIF_NAMESPACE,"\">"
"<eventTime>2012-06-14T14:50:54+02:00</eventTime>"
"<event xmlns=\"http://my.namespaces.com/event\">"
"<severity>major</severity>"
"<description>Something terrible happened</description>"
"</event>"
- "</notification>">>);
-make_msg(Xml) when is_binary(Xml) ->
+ "</notification>">>,
+ xml(lists:duplicate(N,Notification));
+make_msg(Xml) when is_binary(Xml) orelse
+ (is_list(Xml) andalso is_binary(hd(Xml))) ->
xml(Xml);
make_msg(Simple) when is_tuple(Simple) ->
xml(from_simple(Simple)).