aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ic/test/erl_client_c_server_SUITE.erl
diff options
context:
space:
mode:
authorNiclas Eklund <[email protected]>2010-09-02 16:15:32 +0200
committerBjörn Gustavsson <[email protected]>2010-09-09 10:47:56 +0200
commit27a5daae33616e662a36ed514c31618d51ad66e3 (patch)
treeda22058ccf804c5de127339ea13dce3e0931f44e /lib/ic/test/erl_client_c_server_SUITE.erl
parent8e9b11172194ff2920bf572ccbe87a070fe54ec4 (diff)
downloadotp-27a5daae33616e662a36ed514c31618d51ad66e3.tar.gz
otp-27a5daae33616e662a36ed514c31618d51ad66e3.tar.bz2
otp-27a5daae33616e662a36ed514c31618d51ad66e3.zip
Add test suite for ic
Diffstat (limited to 'lib/ic/test/erl_client_c_server_SUITE.erl')
-rw-r--r--lib/ic/test/erl_client_c_server_SUITE.erl350
1 files changed, 350 insertions, 0 deletions
diff --git a/lib/ic/test/erl_client_c_server_SUITE.erl b/lib/ic/test/erl_client_c_server_SUITE.erl
new file mode 100644
index 0000000000..c5f5b6a218
--- /dev/null
+++ b/lib/ic/test/erl_client_c_server_SUITE.erl
@@ -0,0 +1,350 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+%%----------------------------------------------------------------------
+%% Purpose : Test suite for erl-client/c-server
+%%----------------------------------------------------------------------
+
+
+-module(erl_client_c_server_SUITE).
+-include("test_server.hrl").
+
+-export([init_per_testcase/2, fin_per_testcase/2, all/1, void_test/1,
+ long_test/1, longlong_test/1, ushort_test/1, ulong_test/1,
+ ulonglong_test/1, double_test/1, char_test/1, wchar_test/1,
+ octet_test/1, bool_test/1, struct_test/1, struct2_test/1,
+ seq1_test/1, seq2_test/1, seq3_test/1, seq4_test/1,
+ seq5_test/1, array1_test/1, array2_test/1, enum_test/1,
+ string1_test/1, string2_test/1, string3_test/1,
+ string4_test/1, pid_test/1, port_test/1, ref_test/1,
+ term_test/1, typedef_test/1, inline_sequence_test/1,
+ term_sequence_test/1, term_struct_test/1, wstring1_test/1]).
+
+-define(DEFAULT_TIMEOUT, 20000).
+-define(PORT_TIMEOUT, 15000).
+-define(CALL_TIMEOUT, 5000).
+
+-define(C_SERVER_NODE_NAME, idl_c_server_test).
+
+%% Add/remove code path and watchdog before/after each test case.
+%%
+init_per_testcase(_Case, Config) ->
+ DataDir = ?config(data_dir, Config),
+ code:add_patha(DataDir),
+
+ %% Since other test suites use the module m_i, we have
+ %% to make sure we are using the right m_i module.
+ code:purge(m_i),
+ code:load_file(m_i),
+
+ WatchDog = test_server:timetrap(?DEFAULT_TIMEOUT),
+ [{watchdog, WatchDog}| Config].
+
+fin_per_testcase(_Case, Config) ->
+ DataDir = ?config(data_dir, Config),
+ code:del_path(DataDir),
+ WatchDog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(WatchDog).
+
+all(doc) ->
+ "Test of IC with an Erlang client and a C server. "
+ "The communication is via Erlang distribution.";
+all(suite) ->
+ [void_test, long_test, longlong_test, ushort_test,
+ ulong_test, ulonglong_test, double_test,
+ char_test, wchar_test, octet_test, bool_test, struct_test,
+ struct2_test, seq1_test, seq2_test, seq3_test, seq4_test,
+ seq5_test, array1_test, array2_test, enum_test, string1_test,
+ string2_test, string3_test, string4_test, pid_test, port_test,
+ ref_test, term_test, typedef_test, inline_sequence_test,
+ term_sequence_test, term_struct_test, wstring1_test].
+
+
+array1_test(doc) -> "";
+array1_test(suite) -> [];
+array1_test(Config) ->
+ do_test(array1_test, Config).
+
+array2_test(doc) -> "";
+array2_test(suite) -> [];
+array2_test(Config) ->
+ do_test(array2_test, Config).
+
+bool_test(doc) -> "";
+bool_test(suite) -> [];
+bool_test(Config) ->
+ do_test(bool_test, Config).
+
+char_test(doc) -> "";
+char_test(suite) -> [];
+char_test(Config) ->
+ do_test(char_test, Config).
+
+double_test(doc) -> "";
+double_test(suite) -> [];
+double_test(Config) ->
+ do_test(double_test, Config).
+
+enum_test(doc) -> "";
+enum_test(suite) -> [];
+enum_test(Config) ->
+ do_test(enum_test, Config).
+
+inline_sequence_test(doc) -> "";
+inline_sequence_test(suite) -> [];
+inline_sequence_test(Config) ->
+ do_test(inline_sequence_test, Config).
+
+longlong_test(doc) -> "";
+longlong_test(suite) -> [];
+longlong_test(Config) ->
+ do_test(longlong_test, Config).
+
+long_test(doc) -> "";
+long_test(suite) -> [];
+long_test(Config) ->
+ do_test(long_test, Config).
+
+octet_test(doc) -> "";
+octet_test(suite) -> [];
+octet_test(Config) ->
+ do_test(octet_test, Config).
+
+pid_test(doc) -> "";
+pid_test(suite) -> [];
+pid_test(Config) ->
+ do_test(pid_test, Config).
+
+port_test(doc) -> "";
+port_test(suite) -> [];
+port_test(Config) ->
+ do_test(port_test, Config).
+
+ref_test(doc) -> "";
+ref_test(suite) -> [];
+ref_test(Config) ->
+ do_test(ref_test, Config).
+
+seq1_test(doc) -> "";
+seq1_test(suite) -> [];
+seq1_test(Config) ->
+ do_test(seq1_test, Config).
+
+seq2_test(doc) -> "";
+seq2_test(suite) -> [];
+seq2_test(Config) ->
+ do_test(seq2_test, Config).
+
+seq3_test(doc) -> "";
+seq3_test(suite) -> [];
+seq3_test(Config) ->
+ do_test(seq3_test, Config).
+
+seq4_test(doc) -> "";
+seq4_test(suite) -> [];
+seq4_test(Config) ->
+ do_test(seq4_test, Config).
+
+seq5_test(doc) -> "";
+seq5_test(suite) -> [];
+seq5_test(Config) ->
+ do_test(seq5_test, Config).
+
+string1_test(doc) -> "";
+string1_test(suite) -> [];
+string1_test(Config) ->
+ do_test(string1_test, Config).
+
+string2_test(doc) -> "";
+string2_test(suite) -> [];
+string2_test(Config) ->
+ do_test(string2_test, Config).
+
+string3_test(doc) -> "";
+string3_test(suite) -> [];
+string3_test(Config) ->
+ do_test(string3_test, Config).
+
+string4_test(doc) -> "";
+string4_test(suite) -> [];
+string4_test(Config) ->
+ do_test(string4_test, Config).
+
+struct2_test(doc) -> "";
+struct2_test(suite) -> [];
+struct2_test(Config) ->
+ do_test(struct2_test, Config).
+
+struct_test(doc) -> "";
+struct_test(suite) -> [];
+struct_test(Config) ->
+ do_test(struct_test, Config).
+
+term_sequence_test(doc) -> "";
+term_sequence_test(suite) -> [];
+term_sequence_test(Config) ->
+ do_test(term_sequence_test, Config).
+
+term_struct_test(doc) -> "";
+term_struct_test(suite) -> [];
+term_struct_test(Config) ->
+ do_test(term_struct_test, Config).
+
+term_test(doc) -> "";
+term_test(suite) -> [];
+term_test(Config) ->
+ do_test(term_test, Config).
+
+typedef_test(doc) -> "";
+typedef_test(suite) -> [];
+typedef_test(Config) ->
+ do_test(typedef_test, Config).
+
+ulonglong_test(doc) -> "";
+ulonglong_test(suite) -> [];
+ulonglong_test(Config) ->
+ do_test(ulonglong_test, Config).
+
+ulong_test(doc) -> "";
+ulong_test(suite) -> [];
+ulong_test(Config) ->
+ do_test(ulong_test, Config).
+
+ushort_test(doc) -> "";
+ushort_test(suite) -> [];
+ushort_test(Config) ->
+ do_test(ushort_test, Config).
+
+void_test(doc) -> "";
+void_test(suite) -> [];
+void_test(Config) ->
+ do_test(void_test, Config).
+
+wchar_test(doc) -> "";
+wchar_test(suite) -> [];
+wchar_test(Config) ->
+ do_test(wchar_test, Config).
+
+wstring1_test(doc) -> "";
+wstring1_test(suite) -> [];
+wstring1_test(Config) ->
+ do_test(wstring1_test, Config).
+
+
+do_test(Case, Config) ->
+ %% Trap exits
+ process_flag(trap_exit, true),
+ Node = atom_to_list(node()),
+ [_NodeName, HostName] = string:tokens(Node, "@"),
+ DataDir = ?config(data_dir, Config),
+ %% io:format("~p: data directory: ~p~n", [?MODULE, DataDir]),
+ Cookie = atom_to_list(erlang:get_cookie()),
+ ServerNodeName = atom_to_list(?C_SERVER_NODE_NAME),
+ %% Start C-server node as a port program. We wait for the node
+ %% to connect to us.
+ Cmd = filename:join([DataDir, "c_server"]) ++
+ " -this-node-name " ++ ServerNodeName ++
+ " -peer-node " ++ Node ++
+ " -cookie " ++ Cookie,
+ Port = open_port({spawn, Cmd}, [exit_status, eof, stderr_to_stdout]),
+ ServerNode = list_to_atom(ServerNodeName ++ "@" ++ HostName),
+ Res = case wait_for_hidden_node(ServerNode) of
+ ok ->
+ %% Need a port for port_test and typedef_test
+ put(port_test_port, Port),
+ R = (catch erl_client:Case(ServerNode, ?CALL_TIMEOUT)),
+ case wait_for_completion(Port) of
+ {error, timeout} ->
+ kill_off_node(ServerNode);
+ _ ->
+ ok
+ end,
+ R;
+ {error, timeout} ->
+ case wait_for_completion(Port) of
+ {error, timeout} ->
+ kill_off_node(ServerNode);
+ _ ->
+ ok
+ end,
+ {error, timeout}
+ end,
+ process_flag(trap_exit, false),
+ true = Res.
+
+
+%% Wait for eof *and* exit status, but return if exit status indicates
+%% an error, or we have been waiting more than PORT_TIMEOUT seconds.
+%%
+wait_for_completion(Port) ->
+ wait_for_completion(Port, 0).
+
+wait_for_completion(Port, N) when N < 2 ->
+ receive
+ {Port, {data, Bytes}} ->
+ %% Relay output
+ io:format("~s", [Bytes]),
+ wait_for_completion(Port, N);
+ {Port, {exit_status, 0}} ->
+ wait_for_completion(Port, N + 1);
+ {Port, {exit_status, Status}} ->
+ {error, Status};
+ {Port, eof} ->
+ wait_for_completion(Port, N + 1);
+ {'EXIT', Port, Reason} ->
+ io:format("Port exited with reason: ~w~n", [Reason]),
+ wait_for_completion(Port, N);
+ {'EXIT', From, Reason} ->
+ io:format("Got unexpected exit: ~p~n", [{'EXIT', From, Reason}]),
+ wait_for_completion(Port, N)
+ after ?PORT_TIMEOUT ->
+ {error, timeout}
+ end;
+wait_for_completion(_, _) ->
+ ok.
+
+wait_for_hidden_node(Node) ->
+ Times = ?DEFAULT_TIMEOUT div 100,
+ wait_for_hidden_node(Node, Times, 100).
+
+wait_for_hidden_node(Node, Times, WaitTime) when Times > 0 ->
+ io:format("Waiting for hidden node: ~p~n", [Node]),
+ case lists:member(Node, erlang:nodes(hidden)) of
+ true ->
+ ok;
+ false ->
+ delay(WaitTime),
+ wait_for_hidden_node(Node, Times - 1, WaitTime)
+ end;
+wait_for_hidden_node(_Node, _, _WaitTime) ->
+ {error, timeout}.
+
+kill_off_node(Node) ->
+ catch rpc:cast(Node, erlang, halt, [1]).
+
+delay(Time) ->
+ receive
+ after Time ->
+ ok
+ end.
+
+
+
+