aboutsummaryrefslogtreecommitdiffstats
path: root/lib/cosTransactions/test/transactions_SUITE.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/cosTransactions/test/transactions_SUITE.erl')
-rw-r--r--lib/cosTransactions/test/transactions_SUITE.erl395
1 files changed, 395 insertions, 0 deletions
diff --git a/lib/cosTransactions/test/transactions_SUITE.erl b/lib/cosTransactions/test/transactions_SUITE.erl
new file mode 100644
index 0000000000..8385d5a0fb
--- /dev/null
+++ b/lib/cosTransactions/test/transactions_SUITE.erl
@@ -0,0 +1,395 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-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%
+%%
+%%
+-module(transactions_SUITE).
+
+%%--------------- INCLUDES -----------------------------------
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/include/ifr_types.hrl").
+
+%% Local
+-include_lib("cosTransactions/src/ETraP_Common.hrl").
+-include_lib("cosTransactions/include/CosTransactions.hrl").
+-include("etrap_test_lib.hrl").
+
+-include("test_server.hrl").
+
+-define(default_timeout, ?t:minutes(20)).
+
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/1, cases/0, init_all/1, finish_all/1, resource_api/1, etrap_api/1,
+ init_per_testcase/2, fin_per_testcase/2, app_test/1]).
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+all(doc) -> ["API tests for the cosTransactions interfaces", ""];
+all(suite) -> {req,
+ [mnesia, orber],
+ {conf, init_all, cases(), finish_all}}.
+
+cases() ->
+ [etrap_api, resource_api, app_test].
+
+
+
+%%-----------------------------------------------------------------
+%% Init and cleanup functions.
+%%-----------------------------------------------------------------
+
+init_per_testcase(_Case, Config) ->
+ Path = code:which(?MODULE),
+ code:add_pathz(filename:join(filename:dirname(Path), "idl_output")),
+ 'oe_CosTransactions':'oe_register'(),
+ 'oe_etrap_test':'oe_register'(),
+ ?line Dog=test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+
+fin_per_testcase(_Case, Config) ->
+ 'oe_etrap_test':'oe_unregister'(),
+ 'oe_CosTransactions':'oe_unregister'(),
+ Path = code:which(?MODULE),
+ code:del_path(filename:join(filename:dirname(Path), "idl_output")),
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+init_all(Config) ->
+ mnesia:delete_schema([node()]),
+ mnesia:create_schema([node()]),
+ orber:install([node()]),
+ application:start(mnesia),
+ application:start(orber),
+ if
+ is_list(Config) ->
+ Config;
+ true ->
+ exit("Config not a list")
+ end.
+
+finish_all(Config) ->
+ application:stop(orber),
+ application:stop(mnesia),
+ mnesia:delete_schema([node()]),
+ Config.
+
+%%-----------------------------------------------------------------
+%% Tests app file
+%%-----------------------------------------------------------------
+app_test(doc) -> [];
+app_test(suite) -> [];
+app_test(_Config) ->
+ ok=test_server:app_test(cosTransactions),
+ ok.
+
+%%-----------------------------------------------------------------
+%% API tests
+%%-----------------------------------------------------------------
+etrap_api(doc) -> ["ETraP_Server tests", ""];
+etrap_api(suite) -> [];
+etrap_api(_Config) ->
+ ?line ?match(ok, application:start(cosTransactions),
+ "Starting the cosTransactions application"),
+ ?line TrFac = cosTransactions:start_factory(),
+ %% Start a new transaction:
+ %% RootCoord
+ %% / \
+ %% SubCoord1 SubCoord2
+ Control = 'CosTransactions_TransactionFactory':create(TrFac, 0),
+ Term = 'CosTransactions_Control':get_terminator(Control),
+ Coord = 'CosTransactions_Control':get_coordinator(Control),
+ SubCont1 = 'CosTransactions_Coordinator':create_subtransaction(Coord),
+ SubCont2 = 'CosTransactions_Coordinator':create_subtransaction(Coord),
+ SubCoord1 = 'CosTransactions_Control':get_coordinator(SubCont1),
+ SubCoord2 = 'CosTransactions_Control':get_coordinator(SubCont2),
+
+
+ %%------ Test CosTransactions::Coordinator ------
+ ?line ?match(true,
+ 'CosTransactions_Coordinator':is_same_transaction(Coord, Coord),
+ "'CosTransactions_Coordinator':is_same_transaction"),
+ ?line ?match(false,
+ 'CosTransactions_Coordinator':is_same_transaction(Coord, SubCoord1),
+ "'CosTransactions_Coordinator':is_same_transaction"),
+ ?line ?match(true,
+ 'CosTransactions_Coordinator':is_descendant_transaction(Coord, Coord),
+ "'CosTransactions_Coordinator':is_descendant_transaction"),
+ ?line ?match(false,
+ 'CosTransactions_Coordinator':is_descendant_transaction(Coord, SubCoord1),
+ "'CosTransactions_Coordinator':is_descendant_transaction"),
+ ?line ?match(true,
+ 'CosTransactions_Coordinator':is_descendant_transaction(SubCoord1, Coord),
+ "'CosTransactions_Coordinator':is_descendant_transaction"),
+ ?line ?match(false,
+ 'CosTransactions_Coordinator':is_descendant_transaction(SubCoord1, SubCoord2),
+ "'CosTransactions_Coordinator':is_descendant_transaction"),
+ ?line ?match(true,
+ 'CosTransactions_Coordinator':is_top_level_transaction(Coord),
+ "'CosTransactions_Coordinator':is_top_level_transaction"),
+ ?line ?match(false,
+ 'CosTransactions_Coordinator':is_top_level_transaction(SubCoord2),
+ "'CosTransactions_Coordinator':is_top_level_transaction"),
+
+ RootHash = 'CosTransactions_Coordinator':hash_transaction(Coord),
+ RepeatHash= 'CosTransactions_Coordinator':hash_transaction(Coord),
+ RootHash2 = 'CosTransactions_Coordinator':hash_top_level_tran(SubCoord1),
+ RootHash3 = 'CosTransactions_Coordinator':hash_top_level_tran(Coord),
+ _SubHash = 'CosTransactions_Coordinator':hash_transaction(SubCoord2),
+ ?line ?match(RootHash, RepeatHash,
+ "'CosTransactions_Coordinator':hash_transaction"),
+ ?line ?match(RootHash, RootHash2,
+ "'CosTransactions_Coordinator':hash_top_level_tran"),
+ ?line ?match(RootHash, RootHash3,
+ "'CosTransactions_Coordinator':hash_top_level_tran"),
+% ?line ?match_inverse(RootHash, SubHash,
+% "'CosTransactions_Coordinator':hash_transaction"),
+
+ ?line ?match('StatusActive',
+ 'CosTransactions_Coordinator':get_status(Coord),
+ "'CosTransactions_Coordinator':get_status"),
+ ?line ?match('StatusActive',
+ 'CosTransactions_Coordinator':get_status(SubCoord1),
+ "'CosTransactions_Coordinator':get_status"),
+ ?line ?match('StatusActive',
+ 'CosTransactions_Coordinator':get_parent_status(Coord),
+ "'CosTransactions_Coordinator':get_parent_status"),
+ ?line ?match('StatusActive',
+ 'CosTransactions_Coordinator':get_parent_status(SubCoord1),
+ "'CosTransactions_Coordinator':get_parent_status"),
+ ?line ?match('StatusActive',
+ 'CosTransactions_Coordinator':get_top_level_status(Coord),
+ "'CosTransactions_Coordinator':get_top_level_status"),
+ ?line ?match('StatusActive',
+ 'CosTransactions_Coordinator':get_top_level_status(SubCoord1),
+ "'CosTransactions_Coordinator':get_top_level_status"),
+
+ %% Create a CosTransactions::Resource to experiments with.
+ %% Start a new transaction:
+ %% RootCoord
+ %% / \
+ %% SubCoord1 SubCoord2
+ %% /
+ %% Resource
+ N1 = 'ETraP_Common':create_name("test"),
+ O1 = etrap_test_server:oe_create(?nop, {global, N1}),
+ _RC1 = 'CosTransactions_Coordinator':register_resource(SubCoord1, O1),
+% 'CosTransactions_Coordinator':register_synchronization(SubCoord1, O1),
+
+ ?line ?match('VoteCommit',
+ 'CosTransactions_Resource':prepare(SubCoord1),
+ "'CosTransactions_Coordinator':prepare"),
+ %% The Transaction are no longer in 'StatusActive' state. No new
+ %% "members" allowed.
+ ?line ?match('StatusPrepared',
+ 'CosTransactions_Coordinator':get_status(SubCoord1),
+ "'CosTransactions_Coordinator':get_status"),
+% ?line ?match({'EXCEPTION', ?tr_inactive},
+% 'CosTransactions_Coordinator':register_synchronization(SubCoord1, O1),
+% "'CosTransactions_Coordinator':register_synchronization"),
+ ?line ?match({'EXCEPTION', ?tr_inactive},
+ 'CosTransactions_Coordinator':register_resource(SubCoord1, O1),
+ "'CosTransactions_Coordinator':register_resource"),
+ ?line ?match({'EXCEPTION', ?tr_inactive},
+ 'CosTransactions_Coordinator':create_subtransaction(SubCoord1),
+ "'CosTransactions_Coordinator':create_subtransaction"),
+
+ catch corba:dispose(SubCoord1),
+ catch corba:dispose(SubCoord2),
+ catch corba:dispose(SubCont1),
+ catch corba:dispose(SubCont2),
+ catch corba:dispose(Term),
+ catch corba:dispose(Control),
+ catch corba:dispose(Coord),
+ catch corba:dispose(O1),
+
+ ?line cosTransactions:stop_factory(TrFac),
+ ?line application:stop(cosTransactions),
+ ok.
+
+%%-----------------------------------------------------------------
+%% API tests
+%%-----------------------------------------------------------------
+resource_api(doc) -> ["cosTransactions API tests", ""];
+resource_api(suite) -> [];
+resource_api(_Config) ->
+ ?line ?match(ok, application:start(cosTransactions),
+ "Starting the cosTransactions application"),
+ ?line TrFac = cosTransactions:start_factory([{typecheck, true}]),
+
+ ?line ?match({'EXCEPTION', #'TRANSACTION_ROLLEDBACK'{completion_status=?COMPLETED_YES}},
+ run(TrFac, 0, {?nop, ?nop, ?nop, ?prepare_rollback}),
+ "TESTCASE #1: Prepare rollback Resource 4"),
+ ?line ?match({'EXCEPTION', ?tr_mixed},
+ run(TrFac, 0, {?nop, ?nop, ?commit_mix, ?nop}),
+ "TESTCASE #2: Heuristic Mixed exception Resource 3"),
+ ?line ?match(ok,
+ run(TrFac, 0, {?nop, ?nop, ?nop, ?nop}),
+ "TESTCASE #3: Normal completion. No errors."),
+ ?line ?match(ok,
+ run(TrFac, 0, {?nop, ?nop, ?nop, ?commit_cm}),
+ "TESTCASE #4: Heuristic Commit Exception Resource 4"),
+ ?line ?match({'EXCEPTION', #'TRANSACTION_ROLLEDBACK'{completion_status=?COMPLETED_YES}},
+ run(TrFac, 0, {?nop, ?rollback_rb, ?nop, ?prepare_rollback}),
+ "TESTCASE #5: Heuristic Rollbac Resource 2, Resource 4 reply 'VoteRollback'"),
+ ?line ?match({'EXCEPTION', #'TRANSACTION_ROLLEDBACK'{completion_status=?COMPLETED_YES}},
+ run(TrFac, 0, {?nop, ?nop, ?prepare_rollback, ?rollback_rb}),
+ "TESTCASE #6: Heuristic Rollbac Resource 4, Resource 3 reply 'VoteRollback'"),
+ ?line ?match(ok,
+ run(TrFac, 0, {?nop, ?nop, ?commit_delay, ?nop}),
+ "TESTCASE #7: Resource 3 delay during commit. No timeout."),
+ ?line ?match(ok,
+ run(TrFac, 0, {?nop, ?nop, ?prepare_delay, ?nop}),
+ "TESTCASE #8: Resource 3 delay during prepare. No timeout."),
+ ?line ?match(ok,
+ run(TrFac, ?TIMEOUT, {?nop, ?commit_delay, ?nop, ?nop}),
+ "TESTCASE #9: Resource 3 delay during commit. Timeout."),
+ ?line ?match({'EXCEPTION', #'TRANSACTION_ROLLEDBACK'{completion_status=?COMPLETED_YES}},
+ run(TrFac, ?TIMEOUT, {?nop, ?prepare_delay, ?nop, ?nop}),
+ "TESTCASE #10: Resource 3 delay during prepare. Timeout."),
+ case ?is_debug_compiled of
+ true ->
+ %% Testing the Coordinators (root and sub).
+ ?line ?match(ok,
+ run(TrFac, 0, {?nop, ?nop, ?nop, ?nop, [?nop, ?nop,?crash_transient(commit), ?nop]}),
+ "TESTCASE #11: SubCoord 3 crash transient during commit."),
+ ?line ?match({'EXCEPTION', #'TRANSACTION_ROLLEDBACK'{}},
+ run(TrFac, 0, {?nop, ?nop, ?nop, ?nop, [?nop, ?nop,?crash_transient(send_prepare), ?nop]}),
+ "TESTCASE #12: SubCoord 3 crash transient during send prepare."),
+ ?line ?match({'EXCEPTION', ?tr_hazard},
+ run(TrFac, 0, {?nop, ?nop, ?nop, ?nop, [?nop, ?nop,?crash_permanent(commit), ?nop]}),
+ "TESTCASE #13: SubCoord 3 crash permanent during commit."),
+ ?line ?match({'EXCEPTION', #'TRANSACTION_ROLLEDBACK'{}},
+ run(TrFac, 0, {?nop, ?nop, ?nop, ?nop, [?nop, ?nop,?crash_permanent(send_prepare), ?nop]}),
+ "TESTCASE #14: SubCoord 3 crash permanent during prepare."),
+ ?line ?match({'EXCEPTION', #'TRANSACTION_ROLLEDBACK'{}},
+ run(TrFac, 0, {?nop, ?nop, ?nop, ?nop, [?nop, ?crash_transient(send_prepare), ?crash_transient(commit), ?nop]}),
+ "TESTCASE #15: SubCoord 2 crash transient during prepare. SubCoord 3 crash transient during commit"),
+ ?line ?match({'EXCEPTION', #'TRANSACTION_ROLLEDBACK'{completion_status=?COMPLETED_YES}},
+ run(TrFac, 0, {?nop, ?nop, ?nop, ?nop, [?crash_transient(send_prepare), ?nop, ?nop, ?nop]}),
+ "TESTCASE #16: RootCoord crash transient during send prepare."),
+ ?line ?match({'EXCEPTION', #'TRANSACTION_ROLLEDBACK'{}},
+ run(TrFac, 0, {?nop, ?nop, ?nop, ?nop, [?nop, ?crash_transient(prepare1), ?nop, ?nop]}),
+ "TESTCASE #17: SubCoord 1 crash transient during prepare1."),
+ ?line ?match({'EXCEPTION', ?tr_mixed},
+ run(TrFac, 0, {?nop, ?prepare_mix, ?nop, ?nop, [?nop, ?nop, ?crash_transient(prepare2), ?nop]}),
+ "TESTCASE #18: SubCoord 3 crash transient during prepare2. Resource 2 raise Heuristic Mixed during prepare"),
+ ?line ?match({'EXCEPTION', ?tr_mixed},
+ run(TrFac, 0, {?nop, ?commit_mix, ?nop, ?nop, [?nop, ?nop, ?crash_transient(commit2), ?nop]}),
+ "TESTCASE #19: Resource 2 raise Heurist mixed during commit. SubCoord crash transient commit2"),
+ ?line ?match({'EXCEPTION', ?tr_mixed},
+ run(TrFac, 0, {?nop, ?rollback_cm, ?nop, ?prepare_rollback, [?nop, ?crash_transient(rollback2), ?nop, ?nop]}),
+ "TESTCASE #20: Resource 2 raise Heuristic Commit during rollback. Resource 4 'VoteRollback'. SubCoord 2 crash transient rollback2."),
+ ?line ?match({'EXCEPTION', ?tr_mixed},
+ run(TrFac, 0, {?nop, ?nop, ?nop, ?commit_mix, [?nop, ?nop, ?crash_transient(send_forget1), ?nop]}),
+ "TESTCASE #21: Resource 4 raise Heuristic Mixed during commit. SubCoord 2 crash transient send_forget1."),
+ ?line ?match({'EXCEPTION', ?tr_mixed},
+ run(TrFac, 0, {?nop, ?nop, ?nop, ?commit_mix, [?crash_transient(send_forget1), ?nop, ?nop, ?nop]}),
+ "TESTCASE #22: Resource 4 raise Heuristic Mixed during commit. Root Coord crash transient send_forget1."),
+ ?line ?match({'EXCEPTION', ?tr_mixed},
+ run(TrFac, 0, {?nop, ?nop, ?nop, ?commit_mix, [?crash_transient(send_forget3), ?nop, ?crash_transient(send_forget1), ?nop]}),
+ "TESTCASE #23: Resource 4 raise Heuristic Mixed during commit. Root Coord crash transient send_forget3. SubCoord 3 crash transient send_forget1."),
+ ?line ?match({'EXCEPTION', #'TRANSACTION_ROLLEDBACK'{completion_status=?COMPLETED_YES}},
+ run(TrFac, ?TIMEOUT, {?nop, ?nop, ?nop, ?nop, [?delay_transient(root_delay, ?TIMEOUT*2), ?nop, ?nop, ?nop]}),
+ "TESTCASE #24: Delay RootCoord. Timeout."),
+ %% Testing the Terminator.
+ ?line ?match({'EXCEPTION', ?tr_mixed},
+ run(TrFac, ?TIMEOUT, {?nop, ?prepare_mix, ?nop, ?nop, [?nop, ?nop, ?nop, ?crash_transient(commit_heuristic1)]}),
+ "TESTCASE #25: Terminator crash transient after received and logged Heuristic mix."),
+ ?line ?match(ok,
+ run(TrFac, ?TIMEOUT, {?nop, ?nop, ?nop, ?nop, [?nop, ?nop, ?nop, ?crash_transient(commit_ok2)]}),
+ "TESTCASE #26: Terminator crash transient after received and logged 'ok'.");
+ _ ->
+ ok
+ end,
+
+ ?line cosTransactions:stop_factory(TrFac),
+ ?line application:stop(cosTransactions),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Internal functions
+%%-----------------------------------------------------------------
+
+run(TrFac, Time, Spec) ->
+ Control = 'CosTransactions_TransactionFactory':create(TrFac, Time),
+ Term = 'CosTransactions_Control':get_terminator(Control),
+ Coord = 'CosTransactions_Control':get_coordinator(Control),
+ SubCont1 = 'CosTransactions_Coordinator':create_subtransaction(Coord),
+ SubCont2 = 'CosTransactions_Coordinator':create_subtransaction(Coord),
+ SubCoord1 = 'CosTransactions_Control':get_coordinator(SubCont1),
+ SubCoord2 = 'CosTransactions_Control':get_coordinator(SubCont2),
+ %% Start resources/participants.
+ {O1, O2, O3, O4, Ctx} = start_resources(Spec),
+
+ %% Get generated names to use for debugging.
+ CoordN = 'CosTransactions_Coordinator':get_transaction_name(Coord),
+ SubC1N = 'CosTransactions_Coordinator':get_transaction_name(SubCoord1),
+ SubC2N = 'CosTransactions_Coordinator':get_transaction_name(SubCoord2),
+
+ ?set_debug_context([CoordN, SubC1N, SubC2N, Term], Ctx),
+
+ %% Register the resources as participants.
+ _RC1 = 'CosTransactions_Coordinator':register_resource(SubCoord1, O1),
+ _RC2 = 'CosTransactions_Coordinator':register_resource(SubCoord1, O2),
+ _RC3 = 'CosTransactions_Coordinator':register_resource(SubCoord2, O3),
+ _RC4 = 'CosTransactions_Coordinator':register_resource(SubCoord2, O4),
+
+ 'CosTransactions_Coordinator':register_subtran_aware(SubCoord1, O4),
+% 'CosTransactions_Coordinator':register_synchronization(SubCoord1, O2),
+
+% Reply = (catch 'CosTransactions_Terminator':commit(Term, true)),
+ Reply = (catch 'ETraP_Common':send_stubborn('CosTransactions_Terminator',
+ commit, [Term, true],
+ ?tr_max_retries,
+ ?tr_comm_failure_wait)),
+
+ catch corba:dispose(SubCoord1),
+ catch corba:dispose(SubCoord2),
+ catch corba:dispose(SubCont1),
+ catch corba:dispose(SubCont2),
+ catch corba:dispose(Term),
+ catch corba:dispose(Control),
+ catch corba:dispose(Coord),
+ catch corba:dispose(O1),
+ catch corba:dispose(O2),
+ catch corba:dispose(O3),
+ catch corba:dispose(O4),
+ Reply.
+
+
+
+start_resources({A1, A2, A3, A4})->
+ start_resources({A1, A2, A3, A4, ?no_context});
+start_resources({A1, A2, A3, A4, Ctx})->
+ N1 = 'ETraP_Common':create_name("test"),
+ N2 = 'ETraP_Common':create_name("test"),
+ N3 = 'ETraP_Common':create_name("test"),
+ N4 = 'ETraP_Common':create_name("test"),
+ {_,_,O1} = supervisor:start_child(?SUPERVISOR_NAME, ?SUP_TEST(A1, N1)),
+ {_,_,O2} = supervisor:start_child(?SUPERVISOR_NAME, ?SUP_TEST(A2, N2)),
+% {_,_,O2} = supervisor:start_child(?SUPERVISOR_NAME, ?SUP_TEST([{sync,true}|A2], N2)),
+ {_,_,O3} = supervisor:start_child(?SUPERVISOR_NAME, ?SUP_TEST(A3, N3)),
+ {_,_,O4} = supervisor:start_child(?SUPERVISOR_NAME, ?SUP_TEST(A4, N4)),
+ {O1, O2, O3, O4, Ctx}.