1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 2001-2019. 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%%
22%%----------------------------------------------------------------------
23%% Purpose: Test application config
24%%----------------------------------------------------------------------
25
26-module(megaco_examples_SUITE).
27
28-export([
29         suite/0, all/0, groups/0,
30	 init_per_suite/1,    end_per_suite/1,
31         init_per_group/2,    end_per_group/2,
32	 init_per_testcase/2, end_per_testcase/2,
33
34         simple/1
35
36        ]).
37
38
39-include("megaco_test_lib.hrl").
40-include_lib("megaco/include/megaco.hrl").
41-include_lib("megaco/include/megaco_message_v1.hrl").
42
43
44%%======================================================================
45%% Common Test interface functions
46%%======================================================================
47
48suite() ->
49    [{ct_hooks, [ts_install_cth]}].
50
51all() ->
52    [
53     simple
54    ].
55
56groups() ->
57    [].
58
59
60
61%%
62%% -----
63%%
64
65init_per_suite(suite) ->
66    [];
67init_per_suite(doc) ->
68    [];
69init_per_suite(Config0) when is_list(Config0) ->
70
71    ?ANNOUNCE_SUITE_INIT(),
72
73    p("init_per_suite -> entry with"
74      "~n      Config: ~p"
75      "~n      Nodes:  ~p", [Config0, erlang:nodes()]),
76
77    case ?LIB:init_per_suite(Config0) of
78        {skip, _} = SKIP ->
79            SKIP;
80
81        Config1 when is_list(Config1) ->
82
83            %% We need a (local) monitor on this node also
84            megaco_test_sys_monitor:start(),
85
86            p("init_per_suite -> end when"
87              "~n      Config: ~p"
88              "~n      Nodes:  ~p", [Config1, erlang:nodes()]),
89
90            Config1
91    end.
92
93end_per_suite(suite) -> [];
94end_per_suite(doc) -> [];
95end_per_suite(Config0) when is_list(Config0) ->
96
97    p("end_per_suite -> entry with"
98      "~n      Config: ~p"
99      "~n      Nodes:  ~p", [Config0, erlang:nodes()]),
100
101    megaco_test_sys_monitor:stop(),
102    Config1 = ?LIB:end_per_suite(Config0),
103
104    p("end_per_suite -> end when"
105      "~n      Nodes:  ~p", [erlang:nodes()]),
106
107    Config1.
108
109
110%%
111%% -----
112%%
113
114init_per_group(_GroupName, Config) ->
115    Config.
116
117end_per_group(_GroupName, Config) ->
118    Config.
119
120
121%%
122%% -----
123%%
124
125init_per_testcase(Case, Config) ->
126
127    p("init_per_testcase -> entry with"
128      "~n   Config: ~p"
129      "~n   Nodes:  ~p", [Config, erlang:nodes()]),
130
131    megaco_test_global_sys_monitor:reset_events(),
132
133    put(dbg,true),
134    purge_examples(),
135    load_examples(),
136    megaco:enable_trace(max, io),
137
138    megaco_test_lib:init_per_testcase(Case, Config).
139
140end_per_testcase(Case, Config) ->
141
142    p("end_per_testcase -> entry with"
143      "~n   Config: ~p"
144      "~n   Nodes:  ~p", [Config, erlang:nodes()]),
145
146    p("system events during test: "
147      "~n   ~p", [megaco_test_global_sys_monitor:events()]),
148
149    purge_examples(),
150    erase(dbg),
151    megaco:disable_trace(),
152
153    megaco_test_lib:end_per_testcase(Case, Config).
154
155
156example_modules() ->
157    [
158     megaco_simple_mg,
159     megaco_simple_mgc
160    ].
161
162load_examples() ->
163    case code:lib_dir(megaco) of
164	{error, Reason} ->
165	    {error, Reason};
166	Dir ->
167	    SimpleDir = filename:join([Dir, examples, simple]),
168	    case code:add_path(SimpleDir) of
169		true ->
170		    ok;
171		{error, What} ->
172		    error_logger:error_msg("failed adding examples path: "
173					   "~n   ~p"
174					   "~n", [What]),
175		    {error, {failed_add_path, What}}
176	    end
177    end.
178
179
180purge_examples() ->
181    case code:lib_dir(megaco) of
182	{error, Reason} ->
183	    {error, Reason};
184	_Dir ->
185	    [code:purge(M) || M <- example_modules()]
186    end.
187
188
189
190%% ------------------ simple ------------------------
191
192%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
193
194simple(suite) ->
195    [];
196simple(Config) when is_list(Config) ->
197    process_flag(trap_exit, true),
198    d("simple -> create node name(s)"),
199    [_Local, MGC, MG] = ?LIB:mk_nodes(3), %% Grrr
200    Nodes = [MGC, MG],
201
202    d("simple -> start nodes"),
203    ok = ?LIB:start_nodes(Nodes, ?MODULE, ?LINE),
204
205    MGCId = "MGC",
206    MGId  = "MG",
207
208    d("simple -> MGC proxy start (on ~p)", [MGC]),
209    MGCProxy = megaco_test_lib:proxy_start(MGC, "MGC"),
210    ?SLEEP(1000),
211
212    d("simple -> MG proxy start (on ~p)", [MG]),
213    MGProxy  = megaco_test_lib:proxy_start(MG, "MG"),
214    ?SLEEP(1000),
215
216    MegacoStart       = fun() -> megaco:start() end,
217    MegacoStartVerify =
218	 fun(_, ok)    -> ok;
219	    (Id, Else) -> ?ERROR({failed_starting_megaco, Id, Else})
220	 end,
221
222    d("simple -> start MGC megaco"),
223    exec(MGCProxy, MGCId, MegacoStart,
224	 fun(Res) -> MegacoStartVerify(MGCId, Res) end),
225    %% ?APPLY(MGCProxy, fun() -> ok = megaco:start() end),
226    ?SLEEP(1000),
227
228    d("simple -> start MG megaco"),
229    exec(MGProxy, MGId, MegacoStart,
230	 fun(Res) -> MegacoStartVerify(MGId, Res) end),
231    %% ?APPLY(MGProxy, fun() -> ok = megaco:start() end),
232    ?SLEEP(1000),
233
234    d("simple -> start mgc"),
235    start_mgc(MGCProxy),
236    ?SLEEP(1000),
237
238    d("simple -> verify MGC info (no mg)"),
239    info(MGCProxy),
240    ?SLEEP(1000),
241
242    d("simple -> verify MGC system_info(users) (no mg)"),
243    users(MGCProxy),
244    ?SLEEP(1000),
245
246    d("simple -> start mg"),
247    start_mg(MGProxy),
248    ?SLEEP(1000),
249
250    d("simple -> verify MGC info (mg)"),
251    info(MGCProxy),
252    ?SLEEP(1000),
253
254    d("simple -> verify MGC system_info(users) (mg)"),
255    users(MGCProxy),
256    ?SLEEP(1000),
257
258    d("simple -> verify MG info"),
259    info(MGProxy),
260    ?SLEEP(1000),
261
262    d("simple -> verify MG system_info(users)"),
263    users(MGProxy),
264    ?SLEEP(1000),
265
266    d("simple -> stop mgc"),
267    exec(MGCProxy, MGCId,
268	 fun() -> megaco_simple_mgc:stop() end,
269	 fun([_]) -> ok;
270	    (L) when is_list(L) ->
271		 ?ERROR({invalid_users, L});
272	    (X) ->
273		 ?ERROR({invalid_result, X})
274	 end),
275    %% ?VERIFY(5, length()),
276    ?SLEEP(1000),
277
278    d("simple -> verify MGC info (no mgc)"),
279    info(MGCProxy),
280    ?SLEEP(1000),
281
282    d("simple -> verify MG info (no mgc)"),
283    info(MGProxy),
284    ?SLEEP(1000),
285
286    d("simple -> verify MGC system_info(users) (no mgc)",[]),
287    users(MGCProxy),
288    ?SLEEP(1000),
289
290    d("simple -> verify MG system_info(users) (no mgc)",[]),
291    users(MGProxy),
292    ?SLEEP(1000),
293
294    MegacoStop       = fun() -> megaco:stop() end,
295    MegacoStopVerify =
296	 fun(_, ok)    -> ok;
297	    (Id, Else) -> ?ERROR({failed_stop_megaco, Id, Else})
298	 end,
299
300    d("simple -> stop MG megaco",[]),
301    exec(MGProxy, MGId, MegacoStop,
302	 fun(Res) -> MegacoStopVerify(MGId, Res) end),
303    %% ?VERIFY(ok, megaco:stop()),
304    ?SLEEP(1000),
305
306    d("simple -> stop MGC megaco",[]),
307    exec(MGCProxy, MGCId, MegacoStop,
308	 fun(Res) -> MegacoStopVerify(MGCId, Res) end),
309    %% ?VERIFY(ok, megaco:stop()),
310    ?SLEEP(1000),
311
312    d("simple -> kill (exit) MG Proxy: ~p", [MGProxy]),
313    MGProxy ! {stop, self(), normal},
314    receive
315	{'EXIT', MGProxy, _} ->
316	    d("simple -> MG Proxy terminated"),
317	    ok
318    end,
319
320    d("simple -> kill (exit) MGC Proxy: ~p", [MGCProxy]),
321    MGCProxy ! {stop, self(), normal},
322    receive
323	{'EXIT', MGCProxy, _} ->
324	    d("simple -> MGC Proxy terminated"),
325	    ok
326    end,
327
328    d("simple -> stop ~p", [MGC]),
329    slave:stop(MGC),
330
331    d("simple -> stop ~p", [MG]),
332    slave:stop(MG),
333
334    d("simple -> done", []),
335    ok.
336
337
338exec(Proxy, Id, Cmd, Verify) ->
339    ?APPLY(Proxy, Cmd),
340    receive
341	{res, Id, Res} ->
342	    Verify(Res)
343    end.
344
345
346start_mgc(Proxy) ->
347    ?APPLY(Proxy,
348	   fun() ->
349		   try megaco_simple_mgc:start() of
350		       Res ->
351			   Res
352		   catch
353		       C:E:S ->
354			   {error, {{catched, C, E, S}}, code:get_path()}
355		   end
356	   end),
357    receive
358	{res, _, {ok, MgcAll}} when is_list(MgcAll) ->
359	    MgcBad = [MgcRes || MgcRes <- MgcAll, element(1, MgcRes) /= ok],
360	    ?VERIFY([], MgcBad),
361	    ok;
362	Error ->
363	    ?ERROR(Error)
364    end.
365
366
367start_mg(Proxy) ->
368    ?APPLY(Proxy, fun() ->
369			  try megaco_simple_mg:start() of
370			      Res ->
371				  Res
372			  catch
373			      C:E:S ->
374				  {error, {{catched, C, E, S}}, code:get_path()}
375			  end
376		  end),
377    receive
378	{res, _, MGs} when is_list(MGs) andalso (length(MGs) =:= 4) ->
379	    verify_mgs(MGs);
380	Error ->
381	    ?ERROR(Error)
382    end.
383
384verify_mgs(MGs) ->
385    Verify =
386	fun({_MgMid, {TransId, Res}}) when (TransId =:= 1) ->
387		case Res of
388		    {ok, [AR]} when is_record(AR, 'ActionReply') ->
389			case AR#'ActionReply'.commandReply of
390			    [{serviceChangeReply, SCR}] ->
391				case SCR#'ServiceChangeReply'.serviceChangeResult of
392				    {serviceChangeResParms, MgcMid}
393				      when (MgcMid =/= asn1_NOVALUE) ->
394					ok;
395				    Error ->
396					?ERROR(Error)
397				end;
398			    Error ->
399				?ERROR(Error)
400			end;
401		    Error ->
402			?ERROR(Error)
403		end;
404	   (Error) ->
405		?ERROR(Error)
406	end,
407    lists:map(Verify, MGs).
408
409
410info(Proxy) ->
411    ?APPLY(Proxy,
412	   fun() ->
413		   try megaco:info() of
414		       I -> I
415		   catch
416		       C:E:S ->
417			   {error, {C, E, S}}
418		   end
419	   end),
420    receive
421	{res, _, Info} when is_list(Info) ->
422	    ?LOG("Ok, ~p~n", [Info]);
423	{res, _, Error} ->
424	    ?ERROR(Error)
425    end.
426
427
428users(Proxy) ->
429    ?APPLY(Proxy,
430	   fun() ->
431		   try megaco:system_info(users) of
432		       I -> I
433		   catch
434		       C:E:S ->
435			   {error, {C, E, S}}
436		   end
437	   end),
438    receive
439	{res, _, Info} when is_list(Info) ->
440	    ?LOG("Ok, ~p~n", [Info]);
441	{res, _, Error} ->
442	    ?ERROR(Error)
443    end.
444
445
446
447
448%% p(F) ->
449%%     p(F, []).
450
451p(F, A) ->
452    p(get(sname), F, A).
453
454p(S, F, A) when is_list(S) ->
455    io:format("*** [~s] ~p ~s ***"
456	      "~n   " ++ F ++ "~n",
457	      [?FTS(), self(), S | A]);
458p(_S, F, A) ->
459    io:format("*** [~s] ~p *** "
460	      "~n   " ++ F ++ "~n",
461	      [?FTS(), self() | A]).
462
463
464d(F) ->
465    d(F, []).
466d(F, A) ->
467    d(get(dbg), F, A).
468
469d(true, F, A) ->
470    io:format("DBG: ~s " ++ F ++ "~n", [?FTS() | A]);
471d(_, _F, _A) ->
472    ok.
473