1%%--------------------------------------------------------------------
2%%
3%% %CopyrightBegin%
4%%
5%% Copyright Ericsson AB 2000-2016. All Rights Reserved.
6%%
7%% Licensed under the Apache License, Version 2.0 (the "License");
8%% you may not use this file except in compliance with the License.
9%% You may obtain a copy of the License at
10%%
11%%     http://www.apache.org/licenses/LICENSE-2.0
12%%
13%% Unless required by applicable law or agreed to in writing, software
14%% distributed under the License is distributed on an "AS IS" BASIS,
15%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16%% See the License for the specific language governing permissions and
17%% limitations under the License.
18%%
19%% %CopyrightEnd%
20%%
21%%
22%%----------------------------------------------------------------------
23%% File    : time_SUITE.erl
24%% Purpose :
25%%----------------------------------------------------------------------
26
27-module(time_SUITE).
28
29
30%%--------------- INCLUDES -----------------------------------
31-include_lib("cosTime/src/cosTimeApp.hrl").
32
33-include_lib("common_test/include/ct.hrl").
34
35%%--------------- DEFINES ------------------------------------
36-define(default_timeout, test_server:minutes(20)).
37-define(match(ExpectedRes, Expr),
38        fun() ->
39               AcTuAlReS = (catch (Expr)),
40               case AcTuAlReS of
41                   ExpectedRes ->
42                       io:format("------ CORRECT RESULT ------~n~p~n",
43                                 [AcTuAlReS]),
44                       AcTuAlReS;
45                   _ ->
46                       io:format("###### ERROR ERROR ######~n~p~n",
47                                 [AcTuAlReS]),
48                       exit(AcTuAlReS)
49               end
50       end()).
51
52-define(match_inverse(NotExpectedRes, Expr),
53        fun() ->
54                AcTuAlReS = (catch (Expr)),
55               case AcTuAlReS of
56                   NotExpectedRes ->
57                       io:format("###### ERROR ERROR ######~n ~p~n",
58                                 [AcTuAlReS]),
59                       exit(AcTuAlReS);
60                   _ ->
61                       io:format("------ CORRECT RESULT ------~n~p~n",
62                                 [AcTuAlReS]),
63                       AcTuAlReS
64               end
65       end()).
66
67
68%%-----------------------------------------------------------------
69%% External exports
70%%-----------------------------------------------------------------
71-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2, cases/0,
72	 init_per_suite/1, end_per_suite/1, time_api/1, timerevent_api/1,
73	 init_per_testcase/2, end_per_testcase/2,
74	 app_test/1]).
75
76%%-----------------------------------------------------------------
77%% Func: all/1
78%% Args:
79%% Returns:
80%%-----------------------------------------------------------------
81suite() -> [{ct_hooks,[ts_install_cth]}].
82
83all() ->
84    cases().
85
86groups() ->
87    [].
88
89init_per_group(_GroupName, Config) ->
90    Config.
91
92end_per_group(_GroupName, Config) ->
93    Config.
94
95
96cases() ->
97    [time_api, timerevent_api, app_test].
98
99
100
101%%-----------------------------------------------------------------
102%% Init and cleanup functions.
103%%-----------------------------------------------------------------
104
105init_per_testcase(_Case, Config) ->
106    Path = code:which(?MODULE),
107    code:add_pathz(filename:join(filename:dirname(Path), "idl_output")),
108    Dog=test_server:timetrap(?default_timeout),
109    [{watchdog, Dog}|Config].
110
111
112end_per_testcase(_Case, Config) ->
113    Path = code:which(?MODULE),
114    code:del_path(filename:join(filename:dirname(Path), "idl_output")),
115    Dog = proplists:get_value(watchdog, Config),
116    test_server:timetrap_cancel(Dog),
117    ok.
118
119init_per_suite(Config) ->
120    Path = code:which(?MODULE),
121    code:add_pathz(filename:join(filename:dirname(Path), "idl_output")),
122    mnesia:delete_schema([node()]),
123    mnesia:create_schema([node()]),
124    orber:install([node()]),
125    application:start(mnesia),
126    application:start(orber),
127    cosNotificationApp:install_event(),
128    cosNotificationApp:install(),
129    cosTime:install_time(),
130    cosTime:install_timerevent(),
131    if
132        is_list(Config) ->
133	    Config;
134        true ->
135            exit("Config not a list")
136    end.
137
138end_per_suite(Config) ->
139    Path = code:which(?MODULE),
140    code:del_path(filename:join(filename:dirname(Path), "idl_output")),
141    cosTime:uninstall_time(),
142    cosTime:uninstall_timerevent(),
143    cosNotificationApp:uninstall(),
144    cosNotificationApp:uninstall_event(),
145    application:stop(orber),
146    application:stop(mnesia),
147    mnesia:delete_schema([node()]),
148    Config.
149
150%%-----------------------------------------------------------------
151%%  Tests app file
152%%-----------------------------------------------------------------
153app_test(_Config) ->
154    ok=test_server:app_test(cosTime),
155    ok.
156
157%%-----------------------------------------------------------------
158%%  CosTime API tests
159%%-----------------------------------------------------------------
160time_api(_Config) ->
161    ?match(ok, application:start(cosTime)),
162    TS=cosTime:start_time_service(0, 500),
163    Time=calendar:datetime_to_gregorian_seconds({{1582,1,1},{0,0,0}}),
164    Inaccuracy = 1000,
165    Tdf =1,
166    Utc = #'TimeBase_UtcT'{time=Time, inacclo = ?low_TimeT(Inaccuracy),
167			   inacchi = ?high_TimeT(Inaccuracy), tdf = Tdf},
168    UTO1='CosTime_TimeService':new_universal_time(TS, Time, Inaccuracy, Tdf),
169    UTO2='CosTime_TimeService':uto_from_utc(TS, Utc),
170    ?match(Time, 'CosTime_UTO':'_get_time'(UTO1)),
171    ?match(Inaccuracy, 'CosTime_UTO':'_get_inaccuracy'(UTO1)),
172    ?match(Tdf, 'CosTime_UTO':'_get_tdf'(UTO1)),
173    ?match(Utc, 'CosTime_UTO':'_get_utc_time'(UTO1)),
174
175    ?match(Time, 'CosTime_UTO':'_get_time'(UTO2)),
176    ?match(Inaccuracy, 'CosTime_UTO':'_get_inaccuracy'(UTO2)),
177    ?match(Tdf, 'CosTime_UTO':'_get_tdf'(UTO2)),
178    ?match(Utc, 'CosTime_UTO':'_get_utc_time'(UTO2)),
179
180    TIO1='CosTime_TimeService':new_interval(TS, 2, 5),
181    _TIO2='CosTime_TimeService':new_interval(TS, 3, 6),
182    TIO3='CosTime_TimeService':new_interval(TS, 1, 3),
183    TIO4='CosTime_TimeService':new_interval(TS, 3, 4),
184    TIO5='CosTime_TimeService':new_interval(TS, 7, 8),
185    TIO6='CosTime_TimeService':new_interval(TS, 2, 6),
186    TIO7='CosTime_TimeService':new_interval(TS, 3, 7),
187
188    {_,TIO8} = ?match({'OTContained', _}, 'CosTime_TIO':overlaps(TIO1, TIO6)),
189    {_,TIO9} = ?match({'OTContainer', _}, 'CosTime_TIO':overlaps(TIO1, TIO1)),
190    {_,TIO10} = ?match({'OTContainer', _}, 'CosTime_TIO':overlaps(TIO1, TIO4)),
191    {_,TIO11} = ?match({'OTOverlap', _}, 'CosTime_TIO':overlaps(TIO1, TIO3)),
192    {_,TIO12} = ?match({'OTOverlap', _}, 'CosTime_TIO':overlaps(TIO1, TIO7)),
193    {_,TIO13} = ?match({'OTNoOverlap', _}, 'CosTime_TIO':overlaps(TIO1, TIO5)),
194
195    ?match({'TimeBase_IntervalT',2,5},'CosTime_TIO':'_get_time_interval'(TIO8)),
196    ?match({'TimeBase_IntervalT',2,5},'CosTime_TIO':'_get_time_interval'(TIO9)),
197    ?match({'TimeBase_IntervalT',3,4},'CosTime_TIO':'_get_time_interval'(TIO10)),
198    ?match({'TimeBase_IntervalT',2,3},'CosTime_TIO':'_get_time_interval'(TIO11)),
199    ?match({'TimeBase_IntervalT',3,5},'CosTime_TIO':'_get_time_interval'(TIO12)),
200    ?match({'TimeBase_IntervalT',5,7},'CosTime_TIO':'_get_time_interval'(TIO13)),
201
202    UTO3='CosTime_TimeService':new_universal_time(TS, 4, 2, 0), %% 2-6
203    UTO4='CosTime_TimeService':new_universal_time(TS, 2, 1, 0), %% 1-3
204    UTO5='CosTime_TimeService':new_universal_time(TS, 3, 0, 0), %% 3-3
205    UTO6='CosTime_TimeService':new_universal_time(TS, 9, 1, 0), %% 8-10
206    UTO7='CosTime_TimeService':new_universal_time(TS, 4, 3, 0), %% 1-7
207    UTO8='CosTime_TimeService':new_universal_time(TS, 5, 2, 0), %% 3-7
208
209    {_,TIO14} = ?match({'OTContained', _}, 'CosTime_TIO':spans(TIO1, UTO7)),
210    {_,TIO15} = ?match({'OTContainer', _}, 'CosTime_TIO':spans(TIO1, UTO5)),
211    {_,TIO16} = ?match({'OTOverlap', _}, 'CosTime_TIO':spans(TIO1, UTO4)),
212    {_,TIO17} = ?match({'OTOverlap', _}, 'CosTime_TIO':spans(TIO1, UTO8)),
213    {_,TIO18} = ?match({'OTNoOverlap', _}, 'CosTime_TIO':spans(TIO1, UTO6)),
214    {_,TIO19} = ?match({'OTContained', _}, 'CosTime_TIO':spans(TIO1, UTO3)),
215
216    ?match({'TimeBase_IntervalT',2,5},'CosTime_TIO':'_get_time_interval'(TIO14)),
217    ?match({'TimeBase_IntervalT',3,3},'CosTime_TIO':'_get_time_interval'(TIO15)),
218    ?match({'TimeBase_IntervalT',2,3},'CosTime_TIO':'_get_time_interval'(TIO16)),
219    ?match({'TimeBase_IntervalT',3,5},'CosTime_TIO':'_get_time_interval'(TIO17)),
220    ?match({'TimeBase_IntervalT',5,8},'CosTime_TIO':'_get_time_interval'(TIO18)),
221    ?match({'TimeBase_IntervalT',2,5},'CosTime_TIO':'_get_time_interval'(TIO19)),
222
223
224    cosTime:stop_time_service(TS),
225    application:stop(cosTime),
226    ok.
227
228
229%%-----------------------------------------------------------------
230%%  CosTimerEvent API tests
231%%-----------------------------------------------------------------
232timerevent_api(_Config) ->
233    %% Init cosTime apps.
234    ?match(ok, application:start(cosTime)),
235    TS=cosTime:start_time_service(0, 500),
236    TES=cosTime:start_timerevent_service(TS),
237
238    %%----- Initialize the cosNotification application. -----
239    cosNotificationApp:start(),
240    Fac = (catch cosNotificationApp:start_factory([])),
241    {Ch, _Id1} = (catch 'CosNotifyChannelAdmin_EventChannelFactory':create_channel(Fac, [], [])),
242    %% Create the Admin objects
243    {AdminSupplier, _ASID}= ?match({{_,key,_,_,_,_},_},
244             'CosNotifyChannelAdmin_EventChannel':new_for_suppliers(Ch,'OR_OP')),
245    {AdminConsumer, _ACID}= ?match({{_,key,_,_,_,_},_},
246             'CosNotifyChannelAdmin_EventChannel':new_for_consumers(Ch,'OR_OP')),
247
248    %% Create a push consumer TimerEventService will push events to.
249    {ProxyPushConsumer,_ID10}= ?match({{_,key,_,_,_,_},_},
250          'CosNotifyChannelAdmin_SupplierAdmin':obtain_notification_push_consumer(AdminSupplier, 'ANY_EVENT')),
251
252    %% Create a pull suppliers so we can check we actually got the event.
253    {ProxyPullSupplier,_ID1} = ?match({{_,key,_,_,_,_},_},
254	  'CosNotifyChannelAdmin_ConsumerAdmin':obtain_notification_pull_supplier(AdminConsumer, 'ANY_EVENT')),
255
256    AnyEvent = any:create(orber_tc:long(), 100),
257    UTO=?match({_,pseudo,_,_,_,_}, 'CosTime_TimeService':new_universal_time(TS, 10*10000000,1,1)),
258    EH=?match({_,key,_,_,_,_}, 'CosTimerEvent_TimerEventService':register(TES, ProxyPushConsumer, AnyEvent)),
259
260    ?match('ESTimeCleared','CosTimerEvent_TimerEventHandler':'_get_status'(EH)),
261    ?match({false,_},'CosTimerEvent_TimerEventHandler':time_set(EH)),
262    ?match(ok,'CosTimerEvent_TimerEventHandler':set_timer(EH, 'TTRelative', UTO)),
263    ?match({true,_},'CosTimerEvent_TimerEventHandler':time_set(EH)),
264    ?match('ESTimeSet','CosTimerEvent_TimerEventHandler':'_get_status'(EH)),
265
266    ?match({{any,tk_null,null}, false},
267	   'CosNotifyChannelAdmin_ProxyPullSupplier':try_pull(ProxyPullSupplier)),
268
269    ?match(AnyEvent, 'CosNotifyChannelAdmin_ProxyPullSupplier':pull(ProxyPullSupplier)),
270    ?match('ESTriggered','CosTimerEvent_TimerEventHandler':'_get_status'(EH)),
271
272    %% It's allowed to send an UTO with time eq. to 0 if the server is TTRelative.
273    %% When TTAbsolute BAD_PARAM is raised.
274    UTO2=?match({_,pseudo,_,_,_,_}, 'CosTime_TimeService':new_universal_time(TS, 0,1,1)),
275    ?match({'EXCEPTION',_},'CosTimerEvent_TimerEventHandler':set_timer(EH, 'TTAbsolute', UTO2)),
276    ?match(ok,'CosTimerEvent_TimerEventHandler':set_timer(EH, 'TTRelative', UTO2)),
277    ?match(AnyEvent, 'CosNotifyChannelAdmin_ProxyPullSupplier':pull(ProxyPullSupplier)),
278
279    %% TTPeriodic is defined to be relative, i.e., we can use the tactic as above.
280    ?match(ok,'CosTimerEvent_TimerEventHandler':set_timer(EH, 'TTPeriodic', UTO2)),
281
282    %% Sleep for UTO*2+4 secs. At this point the Timer should have delivered 2 events.
283    timer:sleep(24000),
284    %% Cancel the timer so no more events will be delivered.
285    ?match(true,'CosTimerEvent_TimerEventHandler':cancel_timer(EH)),
286
287    ?match({AnyEvent, true}, 'CosNotifyChannelAdmin_ProxyPullSupplier':try_pull(ProxyPullSupplier)),
288    ?match({AnyEvent, true}, 'CosNotifyChannelAdmin_ProxyPullSupplier':try_pull(ProxyPullSupplier)),
289    ?match({{any,tk_null,null}, false},
290	   'CosNotifyChannelAdmin_ProxyPullSupplier':try_pull(ProxyPullSupplier)),
291
292
293
294    %% Clean up.
295    cosNotificationApp:stop(),
296    cosTime:stop_timerevent_service(TES),
297    cosTime:stop_time_service(TS),
298    application:stop(cosTime),
299    ok.
300
301
302