1%% %CopyrightBegin%
2%%
3%% Copyright Ericsson AB 2013. All Rights Reserved.
4%%
5%% Licensed under the Apache License, Version 2.0 (the "License");
6%% you may not use this file except in compliance with the License.
7%% You may obtain a copy of the License at
8%%
9%%     http://www.apache.org/licenses/LICENSE-2.0
10%%
11%% Unless required by applicable law or agreed to in writing, software
12%% distributed under the License is distributed on an "AS IS" BASIS,
13%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14%% See the License for the specific language governing permissions and
15%% limitations under the License.
16%%
17%% %CopyrightEnd%
18%%
19%%
20
21-module(system_information_SUITE).
22
23-include_lib("common_test/include/ct.hrl").
24
25%% Test server callbacks
26-export([suite/0, all/0, groups/0,
27	 init_per_suite/1, end_per_suite/1,
28	 init_per_group/2, end_per_group/2,
29	 init_per_testcase/2, end_per_testcase/2]).
30
31%% Test cases
32-export([
33	%% API-test
34	api_report/1,
35	api_to_file/1,
36	api_from_file/1,
37	sanity_check/1,
38	%% server
39	api_start_stop/1,
40	validate_server_interface/1
41    ]).
42
43%%--------------------------------------------------------------------
44%% COMMON TEST CALLBACK FUNCTIONS
45%%--------------------------------------------------------------------
46%%--------------------------------------------------------------------
47%% Function: groups() -> [Group]
48%%
49%% Group = {GroupName,Properties,GroupsAndTestCases}
50%% GroupName = atom()
51%%   The name of the group.
52%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
53%%   Group properties that may be combined.
54%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
55%% TestCase = atom()
56%%   The name of a test case.
57%% Shuffle = shuffle | {shuffle,Seed}
58%%   To get cases executed in random order.
59%% Seed = {integer(),integer(),integer()}
60%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
61%%              repeat_until_any_ok | repeat_until_any_fail
62%%   To get execution of cases repeated.
63%% N = integer() | forever
64%%
65%% Description: Returns a list of test case group definitions.
66%%--------------------------------------------------------------------
67groups() ->
68    [].
69
70%%--------------------------------------------------------------------
71%% Function: all() -> GroupsAndTestCases | {skip,Reason}
72%%
73%% GroupsAndTestCases = [{group,GroupName} | TestCase]
74%% GroupName = atom()
75%%   Name of a test case group.
76%% TestCase = atom()
77%%   Name of a test case.
78%% Reason = term()
79%%   The reason for skipping all groups and test cases.
80%%
81%% Description: Returns the list of groups and test cases that
82%%              are to be executed.
83%%--------------------------------------------------------------------
84all() -> [
85	api_report,
86	api_to_file,
87	api_from_file,
88	api_start_stop,
89	validate_server_interface,
90	sanity_check
91    ].
92
93
94%%--------------------------------------------------------------------
95%% Function: suite() -> Info
96%%
97%% Info = [tuple()]
98%%   List of key/value pairs.
99%%
100%% Description: Returns list of tuples to set default properties
101%%              for the suite.
102%%
103%% Note: The suite/0 function is only meant to be used to return
104%% default data values, not perform any other operations.
105%%--------------------------------------------------------------------
106suite() -> [
107	{timetrap,{minutes,1}},
108	{ct_hooks,[ts_install_cth]}
109    ].
110
111%%--------------------------------------------------------------------
112%% Function: init_per_suite(Config0) ->
113%%               Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
114%%
115%% Config0 = Config1 = [tuple()]
116%%   A list of key/value pairs, holding the test case configuration.
117%% Reason = term()
118%%   The reason for skipping the suite.
119%%
120%% Description: Initialization before the suite.
121%%
122%% Note: This function is free to add any key/value pairs to the Config
123%% variable, but should NOT alter/remove any existing entries.
124%%--------------------------------------------------------------------
125init_per_suite(Config) ->
126    Config.
127
128%%--------------------------------------------------------------------
129%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
130%%
131%% Config0 = Config1 = [tuple()]
132%%   A list of key/value pairs, holding the test case configuration.
133%%
134%% Description: Cleanup after the suite.
135%%--------------------------------------------------------------------
136end_per_suite(_Config) ->
137    ok.
138
139%%--------------------------------------------------------------------
140%% Function: init_per_group(GroupName, Config0) ->
141%%               Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
142%%
143%% GroupName = atom()
144%%   Name of the test case group that is about to run.
145%% Config0 = Config1 = [tuple()]
146%%   A list of key/value pairs, holding configuration data for the group.
147%% Reason = term()
148%%   The reason for skipping all test cases and subgroups in the group.
149%%
150%% Description: Initialization before each test case group.
151%%--------------------------------------------------------------------
152init_per_group(_GroupName, Config) ->
153    Config.
154
155%%--------------------------------------------------------------------
156%% Function: end_per_group(GroupName, Config0) ->
157%%               void() | {save_config,Config1}
158%%
159%% GroupName = atom()
160%%   Name of the test case group that is finished.
161%% Config0 = Config1 = [tuple()]
162%%   A list of key/value pairs, holding configuration data for the group.
163%%
164%% Description: Cleanup after each test case group.
165%%--------------------------------------------------------------------
166end_per_group(_GroupName, _Config) ->
167    ok.
168
169%%--------------------------------------------------------------------
170%% Function: init_per_testcase(TestCase, Config0) ->
171%%               Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
172%%
173%% TestCase = atom()
174%%   Name of the test case that is about to run.
175%% Config0 = Config1 = [tuple()]
176%%   A list of key/value pairs, holding the test case configuration.
177%% Reason = term()
178%%   The reason for skipping the test case.
179%%
180%% Description: Initialization before each test case.
181%%
182%% Note: This function is free to add any key/value pairs to the Config
183%% variable, but should NOT alter/remove any existing entries.
184%%--------------------------------------------------------------------
185init_per_testcase(_TestCase, Config) ->
186    Config.
187
188%%--------------------------------------------------------------------
189%% Function: end_per_testcase(TestCase, Config0) ->
190%%               void() | {save_config,Config1} | {fail,Reason}
191%%
192%% TestCase = atom()
193%%   Name of the test case that is finished.
194%% Config0 = Config1 = [tuple()]
195%%   A list of key/value pairs, holding the test case configuration.
196%% Reason = term()
197%%   The reason for failing the test case.
198%%
199%% Description: Cleanup after each test case.
200%%--------------------------------------------------------------------
201end_per_testcase(_TestCase, _Config) ->
202    ok.
203
204
205%%--------------------------------------------------------------------
206%% TEST CASES
207%%--------------------------------------------------------------------
208
209%%--------------------------------------------------------------------
210%% Function: TestCase(Config0) ->
211%%               ok | exit() | {skip,Reason} | {comment,Comment} |
212%%               {save_config,Config1} | {skip_and_save,Reason,Config1}
213%%
214%% Config0 = Config1 = [tuple()]
215%%   A list of key/value pairs, holding the test case configuration.
216%% Reason = term()
217%%   The reason for skipping the test case.
218%% Comment = term()
219%%   A comment about the test case that will be printed in the html log.
220%%
221%% Description: Test case function. (The name of it must be specified in
222%%              the all/0 list or in a test case group for the test case
223%%              to be executed).
224%%--------------------------------------------------------------------
225
226
227api_report(_Config) ->
228    Report = system_information:report(),
229    ok     = validate_report(Report),
230    ok.
231
232api_to_file(Config) ->
233    DataDir  = proplists:get_value(data_dir, Config),
234    Filename = filename:join([DataDir, "system_information_report_1.dat"]),
235    ok      = system_information:to_file(Filename),
236    {ok, _} = file:consult(Filename),
237    {save_config, [{report_name, Filename}]}.
238
239api_from_file(Config) ->
240    {api_to_file, Saved} = proplists:get_value(saved_config, Config),
241    DataDir = proplists:get_value(data_dir, Config),
242    Fname1  = filename:join([DataDir, "information_test_report.dat"]),
243    Report1 = system_information:from_file(Fname1),
244    ok      = validate_report(Report1),
245    Fname2  = proplists:get_value(report_name, Saved),
246    Report2 = system_information:from_file(Fname2),
247    ok      = validate_report(Report2),
248    ok.
249
250api_start_stop(_Config) ->
251    {ok, _} = system_information:start(),
252    ok      = system_information:stop(),
253    ok.
254
255validate_server_interface(Config) ->
256    DataDir = proplists:get_value(data_dir, Config),
257    Fname1  = filename:join([DataDir, "information_test_report.dat"]),
258    %% load old report
259    ok = system_information:load_report(file, Fname1),
260    ok = validate_loaded_report(),
261    ok = system_information:stop(),
262    %% load local
263    ok = system_information:load_report(),
264    ok = validate_loaded_report(),
265    ok = system_information:stop(),
266    ok.
267
268sanity_check(Config) when is_list(Config) ->
269    ok = system_information:sanity_check().
270
271
272%% aux
273
274validate_loaded_report() ->
275    ok = system_information:applications(),
276    ok = system_information:applications([full]),
277    ok = system_information:environment(),
278    ok = system_information:environment([full]),
279    ok = system_information:application(kernel),
280    ok = system_information:application(kernel,[full]),
281    ok = system_information:module(gen_server),
282    ok = system_information:module(gen_server,[full]),
283    ok = system_information:modules(native),
284    ok.
285
286
287validate_report([]) -> {error, no_entries};
288validate_report(Report) ->
289    ensure_report_keys([
290	    init_arguments,
291	    code_paths,
292	    code,
293	    system_info,
294	    erts_compile_info,
295	    beam_dynamic_libraries,
296	    environment_erts,
297	    environment,
298	    sanity_check
299	], Report).
300
301ensure_report_keys([], _) -> ok;
302ensure_report_keys([K|Ks], Report) ->
303    case lists:keysearch(K, 1, Report) of
304	false -> {error, key_not_found, K};
305	_     -> ensure_report_keys(Ks, Report)
306    end.
307
308