Skip to content

Commit e4d20bb

Browse files
authored
Merge pull request #12502 from rabbitmq/loic-ct-master-patching
Make CI: Fix and enhance ct_master
2 parents 07898b5 + 4127f15 commit e4d20bb

File tree

10 files changed

+996
-192
lines changed

10 files changed

+996
-192
lines changed

deps/rabbit/Makefile

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -239,22 +239,16 @@ define ct_master.erl
239239
peer:call(Pid2, persistent_term, put, [rabbit_ct_tcp_port_base, 25000]),
240240
peer:call(Pid3, persistent_term, put, [rabbit_ct_tcp_port_base, 27000]),
241241
peer:call(Pid4, persistent_term, put, [rabbit_ct_tcp_port_base, 29000]),
242-
ct_master_fork:run("$1"),
243-
Fail1 = peer:call(Pid1, cth_parallel_ct_detect_failure, has_failures, []),
244-
Fail2 = peer:call(Pid2, cth_parallel_ct_detect_failure, has_failures, []),
245-
Fail3 = peer:call(Pid3, cth_parallel_ct_detect_failure, has_failures, []),
246-
Fail4 = peer:call(Pid4, cth_parallel_ct_detect_failure, has_failures, []),
242+
[{[_], {ok, Results}}] = ct_master_fork:run("$1"),
247243
peer:stop(Pid4),
248244
peer:stop(Pid3),
249245
peer:stop(Pid2),
250246
peer:stop(Pid1),
251-
if
252-
Fail1 -> halt(1);
253-
Fail2 -> halt(2);
254-
Fail3 -> halt(3);
255-
Fail4 -> halt(4);
256-
true -> halt(0)
257-
end
247+
lists:foldl(fun
248+
({_, {_, 0, {_, 0}}}, Err) -> Err + 1;
249+
(What, Peer) -> halt(Peer)
250+
end, 1, Results),
251+
halt(0)
258252
endef
259253

260254
PARALLEL_CT_SET_1_A = amqp_client unit_cluster_formation_locking_mocks unit_cluster_formation_sort_nodes unit_collections unit_config_value_encryption unit_connection_tracking
@@ -293,6 +287,7 @@ define tpl_parallel_ct_test_spec
293287
{logdir, "$(CT_LOGS_DIR)"}.
294288
{logdir, master, "$(CT_LOGS_DIR)"}.
295289
{create_priv_dir, all_nodes, auto_per_run}.
290+
{auto_compile, false}.
296291

297292
{node, shard1, 'rabbit_shard1@localhost'}.
298293
{node, shard2, 'rabbit_shard2@localhost'}.

deps/rabbitmq_ct_helpers/app.bzl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ def all_beam_files(name = "all_beam_files"):
1111
name = "other_beam",
1212
testonly = True,
1313
srcs = [
14+
"src/ct_master_event_fork.erl",
1415
"src/ct_master_fork.erl",
16+
"src/ct_master_logs_fork.erl",
1517
"src/cth_log_redirect_any_domains.erl",
16-
"src/cth_parallel_ct_detect_failure.erl",
1718
"src/rabbit_control_helper.erl",
1819
"src/rabbit_ct_broker_helpers.erl",
1920
"src/rabbit_ct_config_schema.erl",
@@ -39,9 +40,10 @@ def all_test_beam_files(name = "all_test_beam_files"):
3940
name = "test_other_beam",
4041
testonly = True,
4142
srcs = [
43+
"src/ct_master_event_fork.erl",
4244
"src/ct_master_fork.erl",
45+
"src/ct_master_logs_fork.erl",
4346
"src/cth_log_redirect_any_domains.erl",
44-
"src/cth_parallel_ct_detect_failure.erl",
4547
"src/rabbit_control_helper.erl",
4648
"src/rabbit_ct_broker_helpers.erl",
4749
"src/rabbit_ct_config_schema.erl",
@@ -103,9 +105,10 @@ def all_srcs(name = "all_srcs"):
103105
name = "srcs",
104106
testonly = True,
105107
srcs = [
108+
"src/ct_master_event_fork.erl",
106109
"src/ct_master_fork.erl",
110+
"src/ct_master_logs_fork.erl",
107111
"src/cth_log_redirect_any_domains.erl",
108-
"src/cth_parallel_ct_detect_failure.erl",
109112
"src/rabbit_control_helper.erl",
110113
"src/rabbit_ct_broker_helpers.erl",
111114
"src/rabbit_ct_config_schema.erl",
Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
%%
2+
%% %CopyrightBegin%
3+
%%
4+
%% Copyright Ericsson AB 2006-2024. All Rights Reserved.
5+
%%
6+
%% Licensed under the Apache License, Version 2.0 (the "License");
7+
%% you may not use this file except in compliance with the License.
8+
%% You may obtain a copy of the License at
9+
%%
10+
%% http://www.apache.org/licenses/LICENSE-2.0
11+
%%
12+
%% Unless required by applicable law or agreed to in writing, software
13+
%% distributed under the License is distributed on an "AS IS" BASIS,
14+
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
%% See the License for the specific language governing permissions and
16+
%% limitations under the License.
17+
%%
18+
%% %CopyrightEnd%
19+
%%
20+
21+
%%% Common Test Framework Event Handler
22+
%%%
23+
%%% This module implements an event handler that the CT Master
24+
%%% uses to handle status and progress notifications sent to the
25+
%%% master node during test runs. It also keeps track of the
26+
%%% details of failures which are used by the CT Master to print
27+
%%% a summary at the end of its run. This module may be used as a
28+
%%% template for other event handlers that can be plugged in to
29+
%%% handle logging and reporting on the master node.
30+
-module(ct_master_event_fork).
31+
-moduledoc false.
32+
33+
-behaviour(gen_event).
34+
35+
%% API
36+
-export([start_link/0, add_handler/0, add_handler/1, stop/0]).
37+
-export([notify/1, sync_notify/1, get_results/0]).
38+
39+
%% gen_event callbacks
40+
-export([init/1, handle_event/2, handle_call/2,
41+
handle_info/2, terminate/2, code_change/3]).
42+
43+
-include_lib("common_test/include/ct_event.hrl").
44+
-include_lib("common_test/src/ct_util.hrl").
45+
46+
47+
-record(state, {auto_skipped=[], failed=[]}).
48+
49+
%%====================================================================
50+
%% gen_event callbacks
51+
%%====================================================================
52+
%%--------------------------------------------------------------------
53+
%% Function: start_link() -> {ok,Pid} | {error,Error}
54+
%% Description: Creates an event manager.
55+
%%--------------------------------------------------------------------
56+
start_link() ->
57+
gen_event:start_link({local,?CT_MEVMGR}).
58+
59+
%%--------------------------------------------------------------------
60+
%% Function: add_handler() -> ok | {'EXIT',Reason} | term()
61+
%% Description: Adds an event handler
62+
%%--------------------------------------------------------------------
63+
add_handler() ->
64+
gen_event:add_handler(?CT_MEVMGR_REF,?MODULE,[]).
65+
add_handler(Args) ->
66+
gen_event:add_handler(?CT_MEVMGR_REF,?MODULE,Args).
67+
68+
%%--------------------------------------------------------------------
69+
%% Function: stop() -> ok
70+
%% Description: Stops the event manager
71+
%%--------------------------------------------------------------------
72+
stop() ->
73+
case flush() of
74+
{error,Reason} ->
75+
ct_master_logs_fork:log("Error",
76+
"No response from CT Master Event.\n"
77+
"Reason = ~tp\n"
78+
"Terminating now!\n",[Reason]),
79+
%% communication with event manager fails, kill it
80+
catch exit(whereis(?CT_MEVMGR_REF), kill);
81+
_ ->
82+
gen_event:stop(?CT_MEVMGR_REF)
83+
end.
84+
85+
flush() ->
86+
try gen_event:call(?CT_MEVMGR_REF,?MODULE,flush,1800000) of
87+
flushing ->
88+
timer:sleep(1),
89+
flush();
90+
done ->
91+
ok;
92+
Error = {error,_} ->
93+
Error
94+
catch
95+
_:Reason ->
96+
{error,Reason}
97+
end.
98+
99+
%%--------------------------------------------------------------------
100+
%% Function: notify(Event) -> ok
101+
%% Description: Asynchronous notification to event manager.
102+
%%--------------------------------------------------------------------
103+
notify(Event) ->
104+
gen_event:notify(?CT_MEVMGR_REF,Event).
105+
106+
%%--------------------------------------------------------------------
107+
%% Function: sync_notify(Event) -> ok
108+
%% Description: Synchronous notification to event manager.
109+
%%--------------------------------------------------------------------
110+
sync_notify(Event) ->
111+
gen_event:sync_notify(?CT_MEVMGR_REF,Event).
112+
113+
%%--------------------------------------------------------------------
114+
%% Function: sync_notify(Event) -> Results
115+
%% Description: Get the results for auto-skipped and failed test cases.
116+
%%--------------------------------------------------------------------
117+
get_results() ->
118+
gen_event:call(?CT_MEVMGR_REF,?MODULE,get_results).
119+
120+
%%====================================================================
121+
%% gen_event callbacks
122+
%%====================================================================
123+
%%--------------------------------------------------------------------
124+
%% Function: init(Args) -> {ok, State}
125+
%% Description: Whenever a new event handler is added to an event manager,
126+
%% this function is called to initialize the event handler.
127+
%%--------------------------------------------------------------------
128+
init(_) ->
129+
ct_util:mark_process(),
130+
ct_master_logs_fork:log("CT Master Event Handler started","",[]),
131+
{ok,#state{}}.
132+
133+
%%--------------------------------------------------------------------
134+
%% Function:
135+
%% handle_event(Event, State) -> {ok, State} |
136+
%% {swap_handler, Args1, State1, Mod2, Args2} |
137+
%% remove_handler
138+
%% Description:Whenever an event manager receives an event sent using
139+
%% gen_event:notify/2 or gen_event:sync_notify/2, this function is called for
140+
%% each installed event handler to handle the event.
141+
%%--------------------------------------------------------------------
142+
handle_event(#event{name=start_logging,node=Node,data=RunDir},State) ->
143+
ct_master_logs_fork:log("CT Master Event Handler","Got ~ts from ~w",[RunDir,Node]),
144+
ct_master_logs_fork:nodedir(Node,RunDir),
145+
{ok,State};
146+
147+
handle_event(Event=#event{name=Name,node=Node,data=Data},State) ->
148+
print("~n=== ~w ===~n", [?MODULE]),
149+
print("~tw on ~w: ~tp~n", [Name,Node,Data]),
150+
{ok,maybe_store_event(Event,State)}.
151+
152+
%%--------------------------------------------------------------------
153+
%% Function:
154+
%% handle_call(Request, State) -> {ok, Reply, State} |
155+
%% {swap_handler, Reply, Args1, State1,
156+
%% Mod2, Args2} |
157+
%% {remove_handler, Reply}
158+
%% Description: Whenever an event manager receives a request sent using
159+
%% gen_event:call/3,4, this function is called for the specified event
160+
%% handler to handle the request.
161+
%%--------------------------------------------------------------------
162+
handle_call(get_results,State=#state{auto_skipped=AutoSkipped,failed=Failed}) ->
163+
{ok,#{
164+
auto_skipped => lists:sort(AutoSkipped),
165+
failed => lists:sort(Failed)
166+
},State};
167+
handle_call(flush,State) ->
168+
case process_info(self(),message_queue_len) of
169+
{message_queue_len,0} ->
170+
{ok,done,State};
171+
_ ->
172+
{ok,flushing,State}
173+
end.
174+
175+
%%--------------------------------------------------------------------
176+
%% Function:
177+
%% handle_info(Info, State) -> {ok, State} |
178+
%% {swap_handler, Args1, State1, Mod2, Args2} |
179+
%% remove_handler
180+
%% Description: This function is called for each installed event handler when
181+
%% an event manager receives any other message than an event or a synchronous
182+
%% request (or a system message).
183+
%%--------------------------------------------------------------------
184+
handle_info(_Info,State) ->
185+
{ok,State}.
186+
187+
%%--------------------------------------------------------------------
188+
%% Function: terminate(Reason, State) -> ok
189+
%% Description:Whenever an event handler is deleted from an event manager,
190+
%% this function is called. It should be the opposite of Module:init/1 and
191+
%% do any necessary cleaning up.
192+
%%--------------------------------------------------------------------
193+
terminate(_Reason,_State) ->
194+
ct_master_logs_fork:log("CT Master Event Handler stopping","",[]),
195+
ok.
196+
197+
%%--------------------------------------------------------------------
198+
%% Function: code_change(OldVsn, State, Extra) -> {ok, NewState}
199+
%% Description: Convert process state when code is changed
200+
%%--------------------------------------------------------------------
201+
code_change(_OldVsn,State,_Extra) ->
202+
{ok,State}.
203+
204+
%%--------------------------------------------------------------------
205+
%%% Internal functions
206+
%%--------------------------------------------------------------------
207+
208+
print(_Str,_Args) ->
209+
% io:format(_Str,_Args),
210+
ok.
211+
212+
maybe_store_event(#event{name=tc_done,node=Node,data={Suite,FuncOrGroup,{auto_skipped,Reason}}},State=#state{auto_skipped=Acc}) ->
213+
State#state{auto_skipped=[{Node,Suite,FuncOrGroup,Reason}|Acc]};
214+
maybe_store_event(#event{name=tc_done,node=Node,data={Suite,FuncOrGroup,{failed,Reason}}},State=#state{failed=Acc}) ->
215+
State#state{failed=[{Node,Suite,FuncOrGroup,Reason}|Acc]};
216+
maybe_store_event(_Event,State) ->
217+
State.

0 commit comments

Comments
 (0)