1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 2006-2016. 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-module(os_sup_SUITE).
21-include_lib("common_test/include/ct.hrl").
22
23%% Test server specific exports
24-export([all/0, suite/0]).
25-export([init_per_suite/1, end_per_suite/1]).
26
27%% Test cases
28-export([message/1]).
29-export([config/1, port/1]).
30
31-define(TAG, test_tag).
32-define(MFA, {?MODULE, test_mfa, [?TAG]}).
33
34-export([test_mfa/2]).
35
36init_per_suite(Config) when is_list(Config) ->
37    spawn(fun() -> message_receptor() end),
38    application:load(os_mon),
39    ok = application:set_env(os_mon, start_os_sup, true),
40    ok = application:set_env(os_mon, os_sup_mfa, ?MFA),
41    ok = application:set_env(os_mon, os_sup_enable, false),
42    ok = application:start(os_mon),
43    Config.
44
45end_per_suite(Config) when is_list(Config) ->
46    application:stop(os_mon),
47    ok = application:set_env(os_mon, start_os_sup, false),
48    MFA = {os_sup, error_report, [std_error]},
49    ok = application:set_env(os_mon, os_sup_mfa, MFA),
50    ok = application:set_env(os_mon, os_sup_enable, true),
51    exit(whereis(message_receptor), done),
52    Config.
53
54suite() ->
55    [{ct_hooks,[ts_install_cth]},
56     {timetrap,{minutes,1}}].
57
58all() ->
59    case test_server:os_type() of
60        {unix, sunos} -> [message, config, port];
61        {win32, _OSname} -> [message];
62        OS ->
63            Str = io_lib:format("os_sup not available for ~p",
64                                [OS]),
65            {skip, lists:flatten(Str)}
66    end.
67
68
69%% Test OS message handling
70message(Config) when is_list(Config) ->
71
72    %% Fake an OS message
73    Data = "10H11386278426HSystem4HTest5HError5HTesto",
74    os_sup_server ! {faked_port, {data, Data}},
75
76    %% Check with message_receptor that it has been received
77    ct:sleep({seconds,1}),
78    Msg =
79    case ?t:os_type() of
80        {unix, sunos} ->
81            {?TAG, Data};
82        {win32, _} ->
83            {?TAG,{{1138,627842,0},"System","Test","Error","Testo"}}
84    end,
85    message_receptor ! {check, self(), Msg},
86    receive
87        {result, true} ->
88            ok;
89        {result, Rec} ->
90            ct:fail({no_message, Rec})
91    end,
92
93    ok.
94
95%% Test configuration
96config(Config) when is_list(Config) ->
97
98    %% os_sup_enable==true and os_sup_own/os_sup_syslogconf cannot
99    %% be tested as test_server is not running is root
100
101    %% os_sup_mfa is already tested, sort of (in init_per_suite)
102
103    %% os_sup_errortag should be tested, however
104
105    ok.
106
107%% Test that os_sup handles a terminating port program
108port(Config) when is_list(Config) ->
109    Str = os:cmd("ps -e | grep '[f]errule'"),
110    case io_lib:fread("~s", Str) of
111        {ok, [Pid], _Rest} ->
112
113            %% Monitor os_sup_server
114            MonRef = erlang:monitor(process, os_sup_server),
115
116            %% Kill the port program
117            case os:cmd("kill -9 " ++ Pid) of
118                [] ->
119
120                    %% os_sup_server should now terminate
121                    receive
122                        {'DOWN', MonRef, _, _, {port_died, _Reason}} ->
123                            ok;
124                        {'DOWN', MonRef, _, _, Reason} ->
125                            ct:fail({unexpected_exit_reason, Reason})
126                    after
127                        3000 ->
128                            ct:fail(still_alive)
129                    end,
130
131                    %% Give os_mon_sup time to restart os_sup
132                    ct:sleep({seconds,3}),
133                    true = is_pid(whereis(os_sup_server)),
134
135                    ok;
136
137                Line ->
138                    erlang:demonitor(MonRef),
139                    {skip, {not_killed, Line}}
140            end;
141        _ ->
142            {skip, {os_pid_not_found}}
143    end.
144
145%%----------------------------------------------------------------------
146%% Auxiliary
147%%----------------------------------------------------------------------
148
149test_mfa(Message, Tag) ->
150    message_receptor ! {Tag, Message}.
151
152message_receptor() ->
153    register(message_receptor, self()),
154    message_receptor([]).
155
156message_receptor(Received) ->
157    receive
158        %% Check if a certain message has been received
159        {check, From, Msg} ->
160            case lists:member(Msg, Received) of
161                true ->
162                    From ! {result, true},
163                    message_receptor(lists:delete(Msg, Received));
164                false ->
165                    From ! {result, Received},
166                    message_receptor(Received)
167            end;
168
169        %% Save all other messages
170        Msg ->
171            message_receptor([Msg|Received])
172    end.
173