1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 2006-2018. 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. This module may be used as a
26%%% template for other event handlers that can be plugged in to
27%%% handle logging and reporting on the master node.
28-module(ct_master_event).
29
30-behaviour(gen_event).
31
32%% API
33-export([start_link/0, add_handler/0, add_handler/1, stop/0]).
34-export([notify/1, sync_notify/1]).
35
36%% gen_event callbacks
37-export([init/1, handle_event/2, handle_call/2,
38	 handle_info/2, terminate/2, code_change/3]).
39
40-include("ct_event.hrl").
41-include("ct_util.hrl").
42
43
44-record(state, {}).
45
46%%====================================================================
47%% gen_event callbacks
48%%====================================================================
49%%--------------------------------------------------------------------
50%% Function: start_link() -> {ok,Pid} | {error,Error}
51%% Description: Creates an event manager.
52%%--------------------------------------------------------------------
53start_link() ->
54    gen_event:start_link({local,?CT_MEVMGR}).
55
56%%--------------------------------------------------------------------
57%% Function: add_handler() -> ok | {'EXIT',Reason} | term()
58%% Description: Adds an event handler
59%%--------------------------------------------------------------------
60add_handler() ->
61    gen_event:add_handler(?CT_MEVMGR_REF,?MODULE,[]).
62add_handler(Args) ->
63    gen_event:add_handler(?CT_MEVMGR_REF,?MODULE,Args).
64
65%%--------------------------------------------------------------------
66%% Function: stop() -> ok
67%% Description: Stops the event manager
68%%--------------------------------------------------------------------
69stop() ->
70    case flush() of
71	{error,Reason} ->
72	    ct_master_logs:log("Error",
73			       "No response from CT Master Event.\n"
74			       "Reason = ~tp\n"
75			       "Terminating now!\n",[Reason]),
76	    %% communication with event manager fails, kill it
77	    catch exit(whereis(?CT_MEVMGR_REF), kill);
78	_ ->
79	    gen_event:stop(?CT_MEVMGR_REF)
80    end.
81
82flush() ->
83    try gen_event:call(?CT_MEVMGR_REF,?MODULE,flush,1800000) of
84	flushing ->
85	    timer:sleep(1),
86	    flush();
87	done ->
88	    ok;
89	Error = {error,_} ->
90	    Error
91    catch
92	_:Reason ->
93	    {error,Reason}
94    end.
95
96%%--------------------------------------------------------------------
97%% Function: notify(Event) -> ok
98%% Description: Asynchronous notification to event manager.
99%%--------------------------------------------------------------------
100notify(Event) ->
101    gen_event:notify(?CT_MEVMGR_REF,Event).
102
103%%--------------------------------------------------------------------
104%% Function: sync_notify(Event) -> ok
105%% Description: Synchronous notification to event manager.
106%%--------------------------------------------------------------------
107sync_notify(Event) ->
108    gen_event:sync_notify(?CT_MEVMGR_REF,Event).
109
110%%====================================================================
111%% gen_event callbacks
112%%====================================================================
113%%--------------------------------------------------------------------
114%% Function: init(Args) -> {ok, State}
115%% Description: Whenever a new event handler is added to an event manager,
116%% this function is called to initialize the event handler.
117%%--------------------------------------------------------------------
118init(_) ->
119    ct_util:mark_process(),
120    ct_master_logs:log("CT Master Event Handler started","",[]),
121    {ok,#state{}}.
122
123%%--------------------------------------------------------------------
124%% Function:
125%% handle_event(Event, State) -> {ok, State} |
126%%                               {swap_handler, Args1, State1, Mod2, Args2} |
127%%                               remove_handler
128%% Description:Whenever an event manager receives an event sent using
129%% gen_event:notify/2 or gen_event:sync_notify/2, this function is called for
130%% each installed event handler to handle the event.
131%%--------------------------------------------------------------------
132handle_event(#event{name=start_logging,node=Node,data=RunDir},State) ->
133    ct_master_logs:log("CT Master Event Handler","Got ~ts from ~w",[RunDir,Node]),
134    ct_master_logs:nodedir(Node,RunDir),
135    {ok,State};
136
137handle_event(#event{name=Name,node=Node,data=Data},State) ->
138    print("~n=== ~w ===~n", [?MODULE]),
139    print("~tw on ~w: ~tp~n", [Name,Node,Data]),
140    {ok,State}.
141
142%%--------------------------------------------------------------------
143%% Function:
144%% handle_call(Request, State) -> {ok, Reply, State} |
145%%                                {swap_handler, Reply, Args1, State1,
146%%                                  Mod2, Args2} |
147%%                                {remove_handler, Reply}
148%% Description: Whenever an event manager receives a request sent using
149%% gen_event:call/3,4, this function is called for the specified event
150%% handler to handle the request.
151%%--------------------------------------------------------------------
152handle_call(flush,State) ->
153    case process_info(self(),message_queue_len) of
154	{message_queue_len,0} ->
155	    {ok,done,State};
156	_ ->
157	    {ok,flushing,State}
158    end.
159
160%%--------------------------------------------------------------------
161%% Function:
162%% handle_info(Info, State) -> {ok, State} |
163%%                             {swap_handler, Args1, State1, Mod2, Args2} |
164%%                              remove_handler
165%% Description: This function is called for each installed event handler when
166%% an event manager receives any other message than an event or a synchronous
167%% request (or a system message).
168%%--------------------------------------------------------------------
169handle_info(_Info,State) ->
170    {ok,State}.
171
172%%--------------------------------------------------------------------
173%% Function: terminate(Reason, State) -> ok
174%% Description:Whenever an event handler is deleted from an event manager,
175%% this function is called. It should be the opposite of Module:init/1 and
176%% do any necessary cleaning up.
177%%--------------------------------------------------------------------
178terminate(_Reason,_State) ->
179    ct_master_logs:log("CT Master Event Handler stopping","",[]),
180    ok.
181
182%%--------------------------------------------------------------------
183%% Function: code_change(OldVsn, State, Extra) -> {ok, NewState}
184%% Description: Convert process state when code is changed
185%%--------------------------------------------------------------------
186code_change(_OldVsn,State,_Extra) ->
187    {ok,State}.
188
189%%--------------------------------------------------------------------
190%%% Internal functions
191%%--------------------------------------------------------------------
192
193print(_Str,_Args) ->
194%    io:format(_Str,_Args),
195    ok.
196