From 171d7e2a161ef9270240aff0fa15a285df21c1ef Mon Sep 17 00:00:00 2001 From: Siri Hansen Date: Fri, 12 Feb 2016 15:04:30 +0100 Subject: [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. --- .../ct_netconfc_SUITE_data/netconfc1_SUITE.erl | 194 ++++++++++++++++++++- 1 file changed, 189 insertions(+), 5 deletions(-) (limited to 'lib/common_test/test/ct_netconfc_SUITE_data/netconfc1_SUITE.erl') 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 = + <<"\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) -> -- cgit v1.2.3