From b183cadcaddde7dc903c3fa5540c55e3f1408595 Mon Sep 17 00:00:00 2001 From: Tobias Schlager Date: Tue, 16 Jul 2013 11:46:58 +0200 Subject: [otp_mibs] Add test suite for range checks and reduction value overflow. --- lib/otp_mibs/test/Makefile | 85 ++++++++++++ lib/otp_mibs/test/otp_mibs_SUITE.cfg | 15 +++ lib/otp_mibs/test/otp_mibs_SUITE.erl | 245 +++++++++++++++++++++++++++++++++++ 3 files changed, 345 insertions(+) create mode 100644 lib/otp_mibs/test/Makefile create mode 100644 lib/otp_mibs/test/otp_mibs_SUITE.cfg create mode 100644 lib/otp_mibs/test/otp_mibs_SUITE.erl diff --git a/lib/otp_mibs/test/Makefile b/lib/otp_mibs/test/Makefile new file mode 100644 index 0000000000..48c1c5c7d8 --- /dev/null +++ b/lib/otp_mibs/test/Makefile @@ -0,0 +1,85 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 1997-2012. All Rights Reserved. +# +# The contents of this file are subject to the Erlang Public License, +# Version 1.1, (the "License"); you may not use this file except in +# compliance with the License. You should have received a copy of the +# Erlang Public License along with this software. If not, it can be +# retrieved online at http://www.erlang.org/. +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +# the License for the specific language governing rights and limitations +# under the License. +# +# %CopyrightEnd% +# +include $(ERL_TOP)/make/target.mk + +include $(ERL_TOP)/make/$(TARGET)/otp.mk + +# ---------------------------------------------------- +# Target Specs +# ---------------------------------------------------- + +MODULES= otp_mibs_SUITE + +EBIN = . + +HRL_FILES= + +ERL_FILES= $(MODULES:%=%.erl) + +TARGET_FILES = $(MODULES:%=$(EBIN)/%.$(EMULATOR)) + +SOURCE = $(ERL_FILES) $(HRL_FILES) + +EMAKEFILE=Emakefile + +# ---------------------------------------------------- +# Release directory specification +# ---------------------------------------------------- +RELSYSDIR = $(RELEASE_PATH)/otp_mibs_test + +# ---------------------------------------------------- +# FLAGS +# ---------------------------------------------------- +ERL_MAKE_FLAGS += +ERL_COMPILE_FLAGS += \ + -I$(ERL_TOP)/lib/test_server/include \ + -I$(ERL_TOP)/lib/snmp/include + +# ---------------------------------------------------- +# Targets +# ---------------------------------------------------- + +make_emakefile: + $(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES)\ + > $(EMAKEFILE) + +tests debug opt: make_emakefile + erl $(ERL_MAKE_FLAGS) -make + +clean: + rm -f $(EMAKEFILE) + rm -f $(TARGET_FILES) + rm -f core *~ + +docs: + + +# ---------------------------------------------------- +# Release Target +# ---------------------------------------------------- +include $(ERL_TOP)/make/otp_release_targets.mk + +release_spec: + +release_tests_spec: make_emakefile + $(INSTALL_DIR) "$(RELSYSDIR)" + $(INSTALL_DATA) $(EMAKEFILE) $(SOURCE) "$(RELSYSDIR)" + $(INSTALL_DATA) otp_mibs_SUITE.cfg "$(RELSYSDIR)" + +release_docs_spec: diff --git a/lib/otp_mibs/test/otp_mibs_SUITE.cfg b/lib/otp_mibs/test/otp_mibs_SUITE.cfg new file mode 100644 index 0000000000..d01cf92104 --- /dev/null +++ b/lib/otp_mibs/test/otp_mibs_SUITE.cfg @@ -0,0 +1,15 @@ +%% -*- erlang -*- +{snmp, + [ + {start_agent,true}, + {users, + [ + {otp_mibs_test,[snmpm_user_default,[]]} + ]}, + {managed_agents, + [ + {otp_mibs_test, [otp_mibs_test, {127,0,0,1}, 4000, []]} + ]}, + {agent_sysname,"Test otp_mibs"}, + {mgr_port,5001} + ]}. diff --git a/lib/otp_mibs/test/otp_mibs_SUITE.erl b/lib/otp_mibs/test/otp_mibs_SUITE.erl new file mode 100644 index 0000000000..5fd52ac2ac --- /dev/null +++ b/lib/otp_mibs/test/otp_mibs_SUITE.erl @@ -0,0 +1,245 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-2012. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +-module(otp_mibs_SUITE). + +%%----------------------------------------------------------------- +%% This suite can no longer be executed standalone, i.e. it must be +%% executed with common test. The reason is that ct_snmp is used +%% instead of the snmp application directly. The suite requires a +%% config file, otp_mibs_SUITE.cfg, found in the same directory as +%% the suite. +%% +%% Execute with: +%% > ct_run -suite otp_mibs_SUITE -config otp_mibs_SUITE.cfg +%%----------------------------------------------------------------- + +-include_lib("test_server/include/test_server.hrl"). +-include_lib("otp_mibs/include/OTP-MIB.hrl"). +-include_lib("snmp/include/snmp_types.hrl"). + +% Test server specific exports +-export([all/0, + suite/0, + groups/0, + init_per_group/2, + end_per_group/2, + init_per_suite/1, + end_per_suite/1, + init_per_testcase/2, + end_per_testcase/2]). + +% Test cases must be exported. +-export([nt_basic_types/1, nt_high_reduction_count/1]). + +-define(TRAP_UDP, 5000). +-define(AGENT_UDP, 4000). +-define(CONF_FILE_VER, [v2]). +-define(SYS_NAME, "Test otp_mibs"). +-define(MAX_MSG_SIZE, 484). +-define(ENGINE_ID, "mgrEngine"). +-define(MGR_PORT, 5001). + +%% Since some cases are only interested in single entries of the OTP-MIB's +%% node table, one row must be chosen. The first row should be sufficient +%% for this. +-define(NODE_ENTRY, 1). + +%%--------------------------------------------------------------------- +%% CT setup +%%--------------------------------------------------------------------- + +init_per_testcase(_Case, Config) when is_list(Config) -> + Dog = test_server:timetrap(test_server:minutes(6)), + [{watchdog, Dog}|Config]. + +end_per_testcase(_Case, Config) when is_list(Config) -> + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + Config. + +suite() -> [{ct_hooks,[ts_install_cth]}, {require, snmp_mgr_agent, snmp}]. + +all() -> [{group, node_table}]. + +groups() -> [{node_table, [], [nt_basic_types, nt_high_reduction_count]}]. + +init_per_group(_GroupName, Config) -> Config. + +end_per_group(_GroupName, Config) -> Config. + +init_per_suite(Config) -> + ?line application:start(sasl), + ?line application:start(mnesia), + ?line application:start(otp_mibs), + + ok = ct_snmp:start(Config,snmp_mgr_agent), + + %% Load the mibs that should be tested + otp_mib:load(snmp_master_agent), + + Config. + +end_per_suite(Config) -> + PrivDir = ?config(priv_dir, Config), + ConfDir = filename:join(PrivDir,"conf"), + DbDir = filename:join(PrivDir,"db"), + MgrDir = filename:join(PrivDir, "mgr"), + + %% Uload mibs + otp_mib:unload(snmp_master_agent), + + %% Clean up + application:stop(snmp), + application:stop(mnesia), + application:stop(otp_mibs), + + del_dir(ConfDir), + del_dir(DbDir), + (catch del_dir(MgrDir)), + ok. + +%%--------------------------------------------------------------------- +%% Test cases +%%--------------------------------------------------------------------- + +nt_basic_types(suite) -> + []; +nt_basic_types(doc) -> + ["Query every item of the node table and check its variable " + "type and content for sensible values."]; +nt_basic_types(Config) when is_list(Config) -> + ok = otp_mib:update_erl_node_table(), + + NodeNameId = ?erlNodeEntry ++ [?erlNodeName, ?NODE_ENTRY], + {noError, 0, [NodeNameVal]} = snmp_get([NodeNameId]), + #varbind{variabletype = 'OCTET STRING'} = NodeNameVal, + true = is_list(NodeNameVal#varbind.value), + + NodeMachineId = ?erlNodeEntry ++ [?erlNodeMachine, ?NODE_ENTRY], + {noError, 0, [NodeMachineVal]} = snmp_get([NodeMachineId]), + #varbind{variabletype = 'OCTET STRING'} = NodeMachineVal, + true = is_list(NodeMachineVal#varbind.value), + + NodeVersionId = ?erlNodeEntry ++ [?erlNodeVersion, ?NODE_ENTRY], + {noError, 0, [NodeVersionVal]} = snmp_get([NodeVersionId]), + #varbind{variabletype = 'OCTET STRING'} = NodeVersionVal, + true = is_list(NodeVersionVal#varbind.value), + + NodeRunQueueId = ?erlNodeEntry ++ [?erlNodeRunQueue, ?NODE_ENTRY], + {noError, 0, [NodeRunQueueVal]} = snmp_get([NodeRunQueueId]), + #varbind{variabletype = 'Unsigned32'} = NodeRunQueueVal, + true = is_integer(NodeRunQueueVal#varbind.value), + NodeRunQueueVal#varbind.value >= 0, + NodeRunQueueVal#varbind.value =< 4294967295, + + NodeRunTimeId = ?erlNodeEntry ++ [?erlNodeRunTime, ?NODE_ENTRY], + {noError, 0, [NodeRunTimeVal]} = snmp_get([NodeRunTimeId]), + #varbind{variabletype = 'Counter64'} = NodeRunTimeVal, + true = is_integer(NodeRunTimeVal#varbind.value), + NodeRunTimeVal#varbind.value >= 0, + NodeRunTimeVal#varbind.value =< 18446744073709551615, + + NodeWallClockId = ?erlNodeEntry ++ [?erlNodeWallClock, ?NODE_ENTRY], + {noError, 0, [NodeWallClockVal]} = snmp_get([NodeWallClockId]), + #varbind{variabletype = 'Counter64'} = NodeWallClockVal, + true = is_integer(NodeWallClockVal#varbind.value), + NodeWallClockVal#varbind.value >= 0, + NodeWallClockVal#varbind.value =< 18446744073709551615, + + NodeReductionsId = ?erlNodeEntry ++ [?erlNodeReductions, ?NODE_ENTRY], + {noError, 0, [NodeReductionsVal]} = snmp_get([NodeReductionsId]), + #varbind{variabletype = 'Counter64'} = NodeReductionsVal, + true = is_integer(NodeReductionsVal#varbind.value), + NodeReductionsVal#varbind.value >= 0, + NodeReductionsVal#varbind.value =< 18446744073709551615, + + NodeProcessesId = ?erlNodeEntry ++ [?erlNodeProcesses, ?NODE_ENTRY], + {noError, 0, [NodeProcessesVal]} = snmp_get([NodeProcessesId]), + #varbind{variabletype = 'Unsigned32'} = NodeProcessesVal, + true = is_integer(NodeProcessesVal#varbind.value), + NodeProcessesVal#varbind.value >= 0, + NodeProcessesVal#varbind.value =< 4294967295, + + NodeInBytesId = ?erlNodeEntry ++ [?erlNodeInBytes, ?NODE_ENTRY], + {noError, 0, [NodeInBytesVal]} = snmp_get([NodeInBytesId]), + #varbind{variabletype = 'Counter64'} = NodeInBytesVal, + true = is_integer(NodeInBytesVal#varbind.value), + NodeInBytesVal#varbind.value >= 0, + NodeInBytesVal#varbind.value =< 18446744073709551615, + + NodeOutBytesId = ?erlNodeEntry ++ [?erlNodeOutBytes, ?NODE_ENTRY], + {noError, 0, [NodeOutBytesVal]} = snmp_get([NodeOutBytesId]), + #varbind{variabletype = 'Counter64'} = NodeOutBytesVal, + true = is_integer(NodeOutBytesVal#varbind.value), + NodeOutBytesVal#varbind.value >= 0, + NodeOutBytesVal#varbind.value =< 18446744073709551615, + + ok. + +nt_high_reduction_count(suite) -> + []; +nt_high_reduction_count(doc) -> + ["Check that no error occurs when the erlNodeReductions field" + "exceeds the 32bit boundary, this may take about 10min."]; +nt_high_reduction_count(Config) when is_list(Config) -> + NodeReductions = ?erlNodeEntry ++ [?erlNodeReductions, ?NODE_ENTRY], + + BumpFun = fun(F, Limit) -> + case erlang:statistics(reductions) of + {Total, _} when Total < Limit -> + F(F, Limit); + _ -> + ok + end + end, + + ok = otp_mib:update_erl_node_table(), + + {noError, 0, [StartVal]} = snmp_get([NodeReductions]), + #varbind{variabletype = 'Counter64'} = StartVal, + true = is_integer(StartVal#varbind.value), + StartVal#varbind.value >= 0, + case StartVal#varbind.value =< 4294967295 of + true -> + ok = otp_mib:update_erl_node_table(), + BumpFun(BumpFun, 4294967295), + {noError, 0, [EndVal]} = snmp_get([NodeReductions]), + #varbind{variabletype = 'Counter64'} = EndVal, + true = is_integer(EndVal#varbind.value), + EndVal#varbind.value >= 4294967295, + EndVal#varbind.value =< 18446744073709551615; + false -> + %% no need to bump more reductions, since the initial get + %% command already returned successfully with a large value + ok + end. + +%%--------------------------------------------------------------------- +%% Internal functions +%%--------------------------------------------------------------------- + +snmp_get(OIdList) -> + ct_snmp:get_values(otp_mibs_test, OIdList, snmp_mgr_agent). + +del_dir(Dir) -> + io:format("Deleting: ~s~n",[Dir]), + {ok, Files} = file:list_dir(Dir), + FullPathFiles = lists:map(fun(File) -> filename:join(Dir, File) end, Files), + lists:foreach(fun file:delete/1, FullPathFiles), + file:del_dir(Dir). -- cgit v1.2.1