%%-*-erlang-*- %%---------------------------------------------------------------------- %% %CopyrightBegin% %% %% Copyright Ericsson AB 2017. All Rights Reserved. %% %% Licensed 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. %% %% %CopyrightEnd% %%---------------------------------------------------------------------- %% File : xmerl_sax_stream_SUITE.erl %%---------------------------------------------------------------------- -module(xmerl_sax_stream_SUITE). -compile(export_all). %%---------------------------------------------------------------------- %% Include files %%---------------------------------------------------------------------- -include_lib("common_test/include/ct.hrl"). -include_lib("kernel/include/file.hrl"). %%====================================================================== %% External functions %%====================================================================== %%---------------------------------------------------------------------- %% Initializations %%---------------------------------------------------------------------- all() -> [ one_document, two_documents, one_document_and_junk, end_of_stream ]. %%---------------------------------------------------------------------- %% Initializations %%---------------------------------------------------------------------- init_per_suite(Config) -> Config. end_per_suite(_Config) -> ok. init_per_testcase(_TestCase, Config) -> Config. end_per_testcase(_Func, _Config) -> ok. %%---------------------------------------------------------------------- %% Tests %%---------------------------------------------------------------------- %%---------------------------------------------------------------------- %% Send One doc over stream one_document(Config) -> Port = 11111, {ok, ListenSocket} = listen(Port), Self = self(), spawn( fun() -> case catch gen_tcp:accept(ListenSocket) of {ok, S} -> Result = xmerl_sax_parser:stream(<<>>, [{continuation_state, S}, {continuation_fun, fun(Sd) -> io:format("Continuation called!!", []), case gen_tcp:recv(Sd, 0) of {ok, Packet} -> io:format("Packet: ~p\n", [Packet]), {Packet, Sd}; {error, Reason} -> throw({error, Reason}) end end}]), Self ! {xmerl_sax, Result}, close(S); Error -> Self ! {xmerl_sax, {error, {accept, Error}}} end end), {ok, SendSocket} = connect(localhost, Port), {ok, Binary} = file:read_file(filename:join([datadir(Config), "xmerl_sax_stream_one.xml"])), send_chunks(SendSocket, Binary), receive {xmerl_sax, {ok, undefined, Rest}} -> <<"\n">> = Rest, io:format("Ok Rest: ~p\n", [Rest]) after 5000 -> ct:fail("Timeout") end, ok. %%---------------------------------------------------------------------- %% Send Two doc over stream two_documents(Config) -> Port = 11111, {ok, ListenSocket} = listen(Port), Self = self(), spawn( fun() -> case catch gen_tcp:accept(ListenSocket) of {ok, S} -> Result = xmerl_sax_parser:stream(<<>>, [{continuation_state, S}, {continuation_fun, fun(Sd) -> io:format("Continuation called!!", []), case gen_tcp:recv(Sd, 0) of {ok, Packet} -> io:format("Packet: ~p\n", [Packet]), {Packet, Sd}; {error, Reason} -> throw({error, Reason}) end end}]), Self ! {xmerl_sax, Result}, close(S); Error -> Self ! {xmerl_sax, {error, {accept, Error}}} end end), {ok, SendSocket} = connect(localhost, Port), {ok, Binary} = file:read_file(filename:join([datadir(Config), "xmerl_sax_stream_two.xml"])), send_chunks(SendSocket, Binary), receive {xmerl_sax, {ok, undefined, Rest}} -> <<"\n> = Rest, io:format("Ok Rest: ~p\n", [Rest]) after 5000 -> ct:fail("Timeout") end, ok. %%---------------------------------------------------------------------- %% Send one doc and then junk on stream one_document_and_junk(Config) -> Port = 11111, {ok, ListenSocket} = listen(Port), Self = self(), spawn( fun() -> case catch gen_tcp:accept(ListenSocket) of {ok, S} -> Result = xmerl_sax_parser:stream(<<>>, [{continuation_state, S}, {continuation_fun, fun(Sd) -> io:format("Continuation called!!", []), case gen_tcp:recv(Sd, 0) of {ok, Packet} -> io:format("Packet: ~p\n", [Packet]), {Packet, Sd}; {error, Reason} -> throw({error, Reason}) end end}]), Self ! {xmerl_sax, Result}, close(S); Error -> Self ! {xmerl_sax, {error, {accept, Error}}} end end), {ok, SendSocket} = connect(localhost, Port), {ok, Binary} = file:read_file(filename:join([datadir(Config), "xmerl_sax_stream_one_junk.xml"])), send_chunks(SendSocket, Binary), receive {xmerl_sax, {ok, undefined, Rest}} -> <<"\nth", _R/binary>> = Rest, io:format("Ok Rest: ~p\n", [Rest]) after 10000 -> ct:fail("Timeout") end, ok. %%---------------------------------------------------------------------- %% Test of continuation when end of stream end_of_stream(Config) -> Stream = <<"hej">>, {ok, undefined, <<>>} = xmerl_sax_parser:stream(Stream, []), ok. %%---------------------------------------------------------------------- %% Utility functions %%---------------------------------------------------------------------- listen(Port) -> case catch gen_tcp:listen(Port, [{active, false}, binary, {keepalive, true}, {reuseaddr,true}]) of {ok, ListenSocket} -> {ok, ListenSocket}; {error, Reason} -> {error, {listen, Reason}} end. close(Socket) -> (catch gen_tcp:close(Socket)). connect(Host, Port) -> Timeout = 5000, % Options1 = check_options(Options), Options = [binary], case catch gen_tcp:connect(Host, Port, Options, Timeout) of {ok, Socket} -> {ok, Socket}; {error, Reason} -> {error, Reason} end. send_chunks(Socket, Binary) -> BSize = erlang:size(Binary), if BSize > 25 -> <> = Binary, case gen_tcp:send(Socket, Head) of ok -> timer:sleep(1000), send_chunks(Socket, Tail); {error,closed} -> ok end; true -> gen_tcp:send(Socket, Binary) end. datadir(Config) -> proplists:get_value(data_dir, Config).