679 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
			
		
		
	
	
			679 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
| # SNMP::Info::Test
 | |
| #
 | |
| # Copyright (c) 2018 Eric Miller
 | |
| # All rights reserved.
 | |
| #
 | |
| # Redistribution and use in source and binary forms, with or without
 | |
| # modification, are permitted provided that the following conditions are met:
 | |
| #
 | |
| #     * Redistributions of source code must retain the above copyright notice,
 | |
| #       this list of conditions and the following disclaimer.
 | |
| #     * Redistributions in binary form must reproduce the above copyright
 | |
| #       notice, this list of conditions and the following disclaimer in the
 | |
| #       documentation and/or other materials provided with the distribution.
 | |
| #     * Neither the name of the University of California, Santa Cruz nor the
 | |
| #       names of its contributors may be used to endorse or promote products
 | |
| #       derived from this software without specific prior written permission.
 | |
| #
 | |
| # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | |
| # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | |
| # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | |
| # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 | |
| # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | |
| # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 | |
| # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | |
| # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 | |
| # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 | |
| # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 | |
| # POSSIBILITY OF SUCH DAMAGE.
 | |
| 
 | |
| package SNMP::Info::Test;
 | |
| 
 | |
| use Test::Class::Most parent => 'My::Test::Class';
 | |
| 
 | |
| use SNMP::Info;
 | |
| 
 | |
| sub _constructor : Tests(11) {
 | |
|   my $test  = shift;
 | |
|   my $class = $test->class;
 | |
|   my $sess  = $test->mock_session;
 | |
| 
 | |
|   can_ok $class, 'new';
 | |
|   isa_ok $test->{info}, $class, '... and the object it returns';
 | |
| 
 | |
|   is(defined $test->{info}{init}, 1, 'mibs initialized');
 | |
|   ok(
 | |
|     scalar keys %{$test->{info}{mibs}},
 | |
|     'mibs subclass data structure initialized'
 | |
|   );
 | |
|   ok(
 | |
|     scalar keys %{$test->{info}{globals}},
 | |
|     'globals subclass data structure initialized'
 | |
|   );
 | |
|   ok(
 | |
|     scalar keys %{$test->{info}{funcs}},
 | |
|     'funcs subclass data structure initialized'
 | |
|   );
 | |
|   ok(
 | |
|     scalar keys %{$test->{info}{munge}},
 | |
|     'munge subclass data structure initialized'
 | |
|   );
 | |
|   is_deeply($test->{info}{store}, {}, 'store initialized');
 | |
| 
 | |
|   is($test->{info}{snmp_comm}, 'public',  'snmp comm arg saved');
 | |
|   is($test->{info}{snmp_ver},  2,         'snmp version arg saved');
 | |
|   is($test->{info}{snmp_user}, 'initial', 'snmp user arg saved');
 | |
| }
 | |
| 
 | |
| sub globals : Tests(2) {
 | |
|   my $test = shift;
 | |
| 
 | |
|   can_ok($test->{info}, 'globals');
 | |
| 
 | |
|   subtest 'Globals can() subtest' => sub {
 | |
| 
 | |
|     my $test_globals = $test->{info}->globals;
 | |
|     foreach my $key (keys %$test_globals) {
 | |
|       can_ok($test->{info}, $key);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| 
 | |
| sub funcs : Tests(2) {
 | |
|   my $test = shift;
 | |
| 
 | |
|   can_ok($test->{info}, 'funcs');
 | |
| 
 | |
|   subtest 'Funcs can() subtest' => sub {
 | |
| 
 | |
|     my $test_funcs = $test->{info}->funcs;
 | |
|     foreach my $key (keys %$test_funcs) {
 | |
|       can_ok($test->{info}, $key);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| 
 | |
| # update() needs to be reworked to discard all args except community
 | |
| # or context as described in documentation
 | |
| sub update : Tests(4) {
 | |
|   my $test = shift;
 | |
| 
 | |
|   # Starting community
 | |
|   is($test->{info}{sess}{Community}, 'public', 'original community');
 | |
| 
 | |
|   # Change community
 | |
|   $test->{info}->update('Community' => 'new_community',);
 | |
|   is($test->{info}{sess}{Community}, 'new_community', 'community changed');
 | |
| 
 | |
|   # Starting context
 | |
|   is($test->{info}{sess}{Context}, '', 'original context');
 | |
| 
 | |
|   # Change context
 | |
|   $test->{info}->update('Context' => 'new_context',);
 | |
|   is($test->{info}->{sess}->{Context}, 'new_context', 'context changed');
 | |
| }
 | |
| 
 | |
| sub cache_and_clear_cache : Tests(9) {
 | |
|   my $test = shift;
 | |
| 
 | |
|   # Isolate tests to cache method. Populated structure of global 'name' and
 | |
|   # func 'i_description'
 | |
|   my $cache_data = {
 | |
|     '_name'          => 'Test-Name',
 | |
|     '_i_description' => 1,
 | |
|     'store'          => {
 | |
|       'i_description' =>
 | |
|         {10 => 'Test-Description-10', 20 => 'Test-Description-20'}
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   # The empty store hash exists upon initialization and remains when the cache
 | |
|   # is cleared.
 | |
|   my $empty_cache = {'store' => {}};
 | |
| 
 | |
|   can_ok($test->{info}, 'cache');
 | |
|   cmp_deeply($empty_cache, $test->{info}->cache(), 'cache starts empty');
 | |
|   ok($test->{info}->cache($cache_data), 'insert test data into cache');
 | |
|   cmp_deeply(
 | |
|     $cache_data,
 | |
|     $test->{info}->cache(),
 | |
|     'cache method returns test data'
 | |
|   );
 | |
|   is($test->{info}->name(),
 | |
|     'Test-Name', 'global method call returned cached data');
 | |
|   cmp_deeply(
 | |
|     $test->{info}->i_description(),
 | |
|     $cache_data->{store}{i_description},
 | |
|     'funcs method call returned cached data'
 | |
|   );
 | |
|   can_ok($test->{info}, 'clear_cache');
 | |
|   ok($test->{info}->clear_cache(), 'cache cleared');
 | |
|   cmp_deeply(
 | |
|     $empty_cache,
 | |
|     $test->{info}->cache(),
 | |
|     'no cached data returned after clear_cache method call'
 | |
|   );
 | |
| }
 | |
| 
 | |
| sub debug : Tests(4) {
 | |
|   my $test = shift;
 | |
| 
 | |
|   can_ok($test->{info}, 'debug');
 | |
| 
 | |
|   ok(
 | |
|     defined $test->{info}{debug}
 | |
|       && $test->{info}{debug} == 0
 | |
|       && $test->{info}->debug() == 0,
 | |
|     'debug initialized off'
 | |
|   );
 | |
|   $test->{info}->debug(1);
 | |
|   ok($test->{info}{debug} && $test->{info}->debug(), 'debug on');
 | |
|   $test->{info}->debug(0);
 | |
|   ok($test->{info}{debug} == 0 && $test->{info}->debug() == 0, 'debug off');
 | |
| }
 | |
| 
 | |
| sub offline : Tests(4) {
 | |
|   my $test = shift;
 | |
| 
 | |
|   can_ok($test->{info}, 'offline');
 | |
| 
 | |
|   ok(!defined $test->{info}{Offline}, 'offline not initialized');
 | |
|   $test->{info}->offline(1);
 | |
|   ok($test->{info}{Offline} && $test->{info}->offline(), 'offline mode on');
 | |
|   $test->{info}->offline(0);
 | |
|   ok($test->{info}{Offline} == 0 && $test->{info}->offline() == 0,
 | |
|     'offline off');
 | |
| }
 | |
| 
 | |
| sub bulkwalk : Tests(4) {
 | |
|   my $test = shift;
 | |
| 
 | |
|   can_ok $test->{info}, 'bulkwalk';
 | |
| 
 | |
|   # Test harness initalizes BulkWalk off, if we didn't provide an arg
 | |
|   # it would not be defined.
 | |
|   ok(
 | |
|     !defined $test->{info}{BulkWalk}
 | |
|       || ($test->{info}{BulkWalk} == 0 && $test->{info}->bulkwalk() == 0),
 | |
|     'bulkwalk initialized off'
 | |
|   );
 | |
|   $test->{info}->bulkwalk(1);
 | |
|   ok($test->{info}{BulkWalk} && $test->{info}->bulkwalk(), 'bulkwalk on');
 | |
|   $test->{info}->bulkwalk(0);
 | |
|   ok($test->{info}{BulkWalk} == 0 && $test->{info}->bulkwalk() == 0,
 | |
|     'bulkwalk off');
 | |
| }
 | |
| 
 | |
| sub loopdetect : Tests(4) {
 | |
|   my $test = shift;
 | |
| 
 | |
|   can_ok $test->{info}, 'loopdetect';
 | |
| 
 | |
|   ok(!defined $test->{info}{LoopDetect}, 'loopdetect not initialized');
 | |
|   $test->{info}->loopdetect(1);
 | |
|   ok($test->{info}{LoopDetect} && $test->{info}->loopdetect(), 'loopdetect on');
 | |
|   $test->{info}->loopdetect(0);
 | |
|   ok($test->{info}{LoopDetect} == 0 && $test->{info}->loopdetect() == 0,
 | |
|     'loopdetect off');
 | |
| }
 | |
| 
 | |
| sub device_type : Tests(8) {
 | |
|   my $test = shift;
 | |
| 
 | |
|   can_ok($test->{info}, 'device_type');
 | |
| 
 | |
|   # Empty args and no SNMP data should result in undef
 | |
|   is($test->{info}->device_type(),
 | |
|     undef, 'No sysServices, no sysDescr results in undef');
 | |
| 
 | |
|   # Populate cache for tests rather than mocking session to limit code hit
 | |
|   # on these tests
 | |
|   my $cache_data
 | |
|     = {'_layers' => '00000000', '_description' => 'My-Test-sysDescr',};
 | |
|   $test->{info}->cache($cache_data);
 | |
| 
 | |
|   is($test->{info}->device_type(),
 | |
|     'SNMP::Info', 'No sysServices and unknown sysDescr results in SNMP::Info');
 | |
| 
 | |
|   $test->{info}->debug(1);
 | |
|   warnings_like { $test->{info}->device_type() }
 | |
|   [{carped => qr/Might give unexpected results/i}],
 | |
|     'No sysServices and unknown sysDescr with debug on gives warning';
 | |
|   $test->{info}->debug(0);
 | |
|   $test->{info}->clear_cache();
 | |
| 
 | |
|   # Test one oid per layer hash just to verify oid mapping, no need to test
 | |
|   # every hash key - chose an id that is unique per layer
 | |
| 
 | |
|   # Layer 3
 | |
|   $cache_data = {
 | |
|     '_layers'      => 4,
 | |
|     '_description' => 'My-Test-sysDescr',
 | |
|     '_id'          => '.1.3.6.1.4.1.18'
 | |
|   };
 | |
|   $test->{info}->cache($cache_data);
 | |
|   is($test->{info}->device_type,
 | |
|     'SNMP::Info::Layer3::BayRS', 'Layer 3 device type by sysObjectID');
 | |
|   $test->{info}->clear_cache();
 | |
| 
 | |
|   # Layer 2
 | |
|   $cache_data = {
 | |
|     '_layers'      => 2,
 | |
|     '_description' => 'My-Test-sysDescr',
 | |
|     '_id'          => '.1.3.6.1.4.1.11898'
 | |
|   };
 | |
|   $test->{info}->cache($cache_data);
 | |
|   is($test->{info}->device_type,
 | |
|     'SNMP::Info::Layer2::Orinoco', 'Layer 2 device type by sysObjectID');
 | |
|   $test->{info}->clear_cache();
 | |
| 
 | |
|   # Layer 1
 | |
|   $cache_data = {
 | |
|     '_layers'      => 1,
 | |
|     '_description' => 'My-Test-sysDescr',
 | |
|     '_id'          => '.1.3.6.1.4.1.2925'
 | |
|   };
 | |
|   $test->{info}->cache($cache_data);
 | |
|   is(
 | |
|     $test->{info}->device_type,
 | |
|     'SNMP::Info::Layer1::Cyclades',
 | |
|     'Layer 1 device type by sysObjectID'
 | |
|   );
 | |
|   $test->{info}->clear_cache();
 | |
| 
 | |
|   # Layer 7
 | |
|   $cache_data = {
 | |
|     '_layers'      => 64,
 | |
|     '_description' => 'My-Test-sysDescr',
 | |
|     '_id'          => '.1.3.6.1.4.1.318'
 | |
|   };
 | |
|   $test->{info}->cache($cache_data);
 | |
|   is($test->{info}->device_type,
 | |
|     'SNMP::Info::Layer7::APC', 'Layer 1 device type by sysObjectID');
 | |
|   $test->{info}->clear_cache();
 | |
| 
 | |
|   # Add Regex tests if needed
 | |
| }
 | |
| 
 | |
| sub error : Tests(7) {
 | |
|   my $test = shift;
 | |
| 
 | |
|   can_ok($test->{info}, 'error');
 | |
|   ok(!exists $test->{info}{error}, 'Error not present');
 | |
|   $test->{info}{error} = 'Test Error';
 | |
|   is($test->{info}->error(), 'Test Error', 'Test Error present');
 | |
|   is($test->{info}->error(), undef,        'Test Error cleared upon read');
 | |
|   $test->{info}{error} = 'Test Error 2';
 | |
|   is($test->{info}->error(1),
 | |
|     'Test Error 2', 'Test Error 2 present and no clear flag set');
 | |
|   is($test->{info}->error(0),
 | |
|     'Test Error 2', 'Test Error 2 still present on next read');
 | |
|   is($test->{info}->error(),
 | |
|     undef, 'Test Error 2 cleared upon read with flag set to false');
 | |
| }
 | |
| 
 | |
| sub has_layer : Tests(6) {
 | |
|   my $test = shift;
 | |
| 
 | |
|   can_ok $test->{info}, 'has_layer';
 | |
|   $test->{info}->clear_cache();
 | |
| 
 | |
|   # Populate cache, one key/value so don't bother going through the
 | |
|   # cache() method.
 | |
|   # Layers holds the unmunged value (decimal)
 | |
|   $test->{info}{'_layers'} = 1;
 | |
|   is($test->{info}->has_layer(1), 1, 'Has layer 1');
 | |
| 
 | |
|   $test->{info}{'_layers'} = 2;
 | |
|   is($test->{info}->has_layer(2), 1, 'Has layer 2');
 | |
| 
 | |
|   $test->{info}{'_layers'} = 4;
 | |
|   is($test->{info}->has_layer(3), 1, 'Has layer 3');
 | |
| 
 | |
|   # We don't use layers 4-6 for classification, skip testing
 | |
| 
 | |
|   $test->{info}{'_layers'} = 64;
 | |
|   is($test->{info}->has_layer(7), 1, 'Has layer 7');
 | |
| 
 | |
|   # Check for undef layers
 | |
|   $test->{info}{'_layers'} = undef;
 | |
|   is($test->{info}->has_layer(7), undef, 'Undef layers returns undef');
 | |
| }
 | |
| 
 | |
| sub snmp_comm : Tests(4) {
 | |
|   my $test = shift;
 | |
| 
 | |
|   can_ok $test->{info}, 'snmp_comm';
 | |
| 
 | |
|   # Define before test to be sure instead of relying on initalization
 | |
|   $test->{info}{snmp_comm} = 'publicv1';
 | |
|   $test->{info}{snmp_ver}  = 1;
 | |
|   is($test->{info}->snmp_comm(), 'publicv1',
 | |
|     'Version 1 returns SNMP community');
 | |
| 
 | |
|   $test->{info}{snmp_comm} = 'publicv2';
 | |
|   $test->{info}{snmp_ver}  = 2;
 | |
|   is($test->{info}->snmp_comm(), 'publicv2',
 | |
|     'Version 2 returns SNMP community');
 | |
| 
 | |
|   $test->{info}{snmp_user} = 'initialv3';
 | |
|   $test->{info}{snmp_ver}  = 3;
 | |
|   is($test->{info}->snmp_comm(), 'initialv3', 'Version 3 returns SNMP user');
 | |
| }
 | |
| 
 | |
| sub snmp_ver : Tests(2) {
 | |
|   my $test = shift;
 | |
| 
 | |
|   can_ok $test->{info}, 'snmp_ver';
 | |
| 
 | |
|   # Define before test to be sure instead of relying on initalization
 | |
|   $test->{info}{snmp_ver} = 1;
 | |
|   is($test->{info}->snmp_ver(), 1, 'SNMP version returned');
 | |
| }
 | |
| 
 | |
| sub specify : Tests(4) {
 | |
|   my $test = shift;
 | |
| 
 | |
|   can_ok $test->{info}, 'specify';
 | |
|   $test->{info}->cache_clear();
 | |
| 
 | |
|   # Specify uses device_type(), use same data as that test to setup
 | |
|   # test cases here since return values from device_type() with them
 | |
|   # have been tested
 | |
| 
 | |
|   # device_type returns undef
 | |
|   $test->{info}->specify();
 | |
|   is(
 | |
|     $test->{info}->error(),
 | |
|     'SNMP::Info::specify() - Could not get info from device',
 | |
|     'Undef device type throws error'
 | |
|   );
 | |
|   $test->{info}->cache_clear();
 | |
| 
 | |
|   # Populate cache for following tests
 | |
|   my $cache_data
 | |
|     = {'_layers' => '00000000', '_description' => 'My-Test-sysDescr',};
 | |
|   $test->{info}->cache($cache_data);
 | |
| 
 | |
|   isa_ok($test->{info}->specify(),
 | |
|     'SNMP::Info', 'SNMP::Info device_type returns self');
 | |
|   $test->{info}->cache_clear();
 | |
| 
 | |
|   # Layer 7 - SNMP::Info::Layer7::APC
 | |
|   $cache_data = {
 | |
|     '_layers'      => 64,
 | |
|     '_description' => 'My-Test-sysDescr',
 | |
|     '_id'          => '.1.3.6.1.4.1.318'
 | |
|   };
 | |
|   $test->{info}->cache($cache_data);
 | |
|   isa_ok($test->{info}->specify(),
 | |
|     'SNMP::Info::Layer7::APC',
 | |
|     'Layer 7 device type returns new object of same type');
 | |
|   $test->{info}->clear_cache();
 | |
| }
 | |
| 
 | |
| sub cisco_comm_indexing : Tests(2) {
 | |
|   my $test = shift;
 | |
| 
 | |
|   can_ok $test->{info}, 'cisco_comm_indexing';
 | |
|   is($test->{info}->cisco_comm_indexing(), 0, 'Cisco community indexing off');
 | |
| }
 | |
| 
 | |
| sub if_ignore : Tests(2) {
 | |
|   my $test = shift;
 | |
| 
 | |
|   can_ok $test->{info}, 'if_ignore';
 | |
|   is_deeply($test->{info}->if_ignore(),
 | |
|     {}, 'No ignored interfaces for this class');
 | |
| }
 | |
| 
 | |
| sub bulkwalk_no : Tests(2) {
 | |
|   my $test = shift;
 | |
| 
 | |
|   can_ok $test->{info}, 'bulkwalk_no';
 | |
|   is($test->{info}->bulkwalk_no(), 0, 'Bulkwalk not turned off in this class');
 | |
| }
 | |
| 
 | |
| sub i_speed : Tests(2) {
 | |
|   my $test = shift;
 | |
| 
 | |
|   can_ok $test->{info}, 'i_speed';
 | |
| 
 | |
|   # Method uses partial fetches which ignores the cache and reloads data
 | |
|   # therefore we must use the mocked session. Populate the session data
 | |
|   # so that the mock_getnext() has data to fetch.
 | |
|   my $data = {
 | |
| 
 | |
|     # Need to use OID for ifSpeed since it could resolve to a fully qualified
 | |
|     # name as either RFC1213-MIB::ifSpeed or IF-MIB::ifSpeed dependent upon
 | |
|     # which MIB got loaded last which is based upon random hash ordering. Using
 | |
|     # a fully qualified name with mock session we would need to know which MIB
 | |
|     # "owned" the OID since the MIB hash is indexed by OID. This is not an
 | |
|     # issue in live code since what is fed to getnext for a fully qualified
 | |
|     # name is what is returned.
 | |
|     '.1.3.6.1.2.1.2.2.1.5' => {38 => 0, 49 => 4294967295, 501 => 1000000000,},
 | |
|     'IF-MIB::ifHighSpeed'  => {38 => 0, 49 => 32000,      501 => 1000,},
 | |
|   };
 | |
|   my $expected = {38 => 0, 49 => '32 Gbps', 501 => '1.0 Gbps',};
 | |
|   $test->{info}{sess}{Data} = $data;
 | |
|   is_deeply($test->{info}->i_speed(),
 | |
|     $expected, 'High speed interface reported accurately');
 | |
| }
 | |
| 
 | |
| sub i_speed_raw : Tests(3) {
 | |
|   my $test = shift;
 | |
| 
 | |
|   can_ok $test->{info}, 'i_speed_raw';
 | |
| 
 | |
|   # Method uses partial fetches which ignores the cache and reloads data
 | |
|   # therefore we must use the mocked session. Populate the session data
 | |
|   # so that the mock_getnext() has data to fetch.
 | |
|   my $data = {
 | |
| 
 | |
|     # Need to use OID for ifSpeed since it could resolve to a fully qualified
 | |
|     # name as either RFC1213-MIB::ifSpeed or IF-MIB::ifSpeed dependent upon
 | |
|     # which MIB got loaded last which is based upon random hash ordering. Using
 | |
|     # a fully qualified name with mock session we would need to know which MIB
 | |
|     # "owned" the OID since the MIB hash is indexed by OID. This is not an
 | |
|     # issue in live code since what is fed to getnext for a fully qualified
 | |
|     # name is what is returned.
 | |
|     '.1.3.6.1.2.1.2.2.1.5' => {38 => 0, 49 => 4294967295, 501 => 1000000000,},
 | |
|     'IF-MIB::ifHighSpeed'  => {38 => 0, 49 => 32000,      501 => 1000,},
 | |
|   };
 | |
|   my $expected     = {38 => 0, 49 => '32 Gbps',   501 => '1.0 Gbps',};
 | |
|   my $expected_raw = {38 => 0, 49 => 32000000000, 501 => 1000000000,};
 | |
|   $test->{info}{sess}{Data} = $data;
 | |
|   is_deeply($test->{info}->i_speed_raw(),
 | |
|     $expected_raw, 'Raw high speed interface reported accurately');
 | |
| 
 | |
|   # Note the cache is populated unmunged data now - not sure if that is
 | |
|   # expected behavior. Clear cache to get data to test that munges are restored.
 | |
|   $test->{info}->clear_cache();
 | |
|   is_deeply($test->{info}->i_speed(),
 | |
|     $expected, 'Munges restored after i_speed_raw() call');
 | |
| }
 | |
| 
 | |
| # Topo routines will need to be tested in sub classes for conditionals
 | |
| sub has_topo : Tests(2) {
 | |
|   my $test = shift;
 | |
| 
 | |
|   can_ok($test->{info}, 'has_topo');
 | |
|   is($test->{info}->has_topo(), undef, 'Base class has no topo');
 | |
| }
 | |
| 
 | |
| sub get_topo_data : Tests(2) {
 | |
|   my $test = shift;
 | |
| 
 | |
|   can_ok($test->{info}, '_get_topo_data');
 | |
|   is($test->{info}->_get_topo_data(), undef, 'Base class has no topo data');
 | |
| }
 | |
| 
 | |
| sub c_ip : Tests(2) {
 | |
|   my $test = shift;
 | |
| 
 | |
|   can_ok($test->{info}, 'c_ip');
 | |
|   is($test->{info}->c_ip(), undef, 'Base class has no topo');
 | |
| }
 | |
| 
 | |
| sub c_if : Tests(2) {
 | |
|   my $test = shift;
 | |
| 
 | |
|   can_ok($test->{info}, 'c_if');
 | |
|   is($test->{info}->c_if(), undef, 'Base class has no topo');
 | |
| }
 | |
| 
 | |
| sub c_port : Tests(2) {
 | |
|   my $test = shift;
 | |
| 
 | |
|   can_ok($test->{info}, 'c_port');
 | |
|   is($test->{info}->c_port(), undef, 'Base class has no topo');
 | |
| }
 | |
| 
 | |
| sub c_id : Tests(2) {
 | |
|   my $test = shift;
 | |
| 
 | |
|   can_ok($test->{info}, 'c_id');
 | |
|   is($test->{info}->c_id(), undef, 'Base class has no topo');
 | |
| }
 | |
| 
 | |
| sub c_platform : Tests(2) {
 | |
|   my $test = shift;
 | |
| 
 | |
|   can_ok($test->{info}, 'c_platform');
 | |
|   is($test->{info}->c_platform(), undef, 'Base class has no topo');
 | |
| }
 | |
| 
 | |
| sub c_cap : Tests(2) {
 | |
|   my $test = shift;
 | |
| 
 | |
|   can_ok($test->{info}, 'c_cap');
 | |
|   is($test->{info}->c_cap(), undef, 'Base class has no topo');
 | |
| }
 | |
| 
 | |
| # Munges aren't methods, the are functions so calling convention is different
 | |
| sub munge_speed : Tests(2) {
 | |
|   my $test = shift;
 | |
| 
 | |
|   can_ok($test->{info}, 'munge_speed');
 | |
|   is(SNMP::Info::munge_speed('2488000000'),
 | |
|     'OC-48', 'Speed munged according to map');
 | |
| }
 | |
| 
 | |
| sub munge_highspeed : Tests(6) {
 | |
|   my $test = shift;
 | |
| 
 | |
|   can_ok($test->{info}, 'munge_highspeed');
 | |
|   is(SNMP::Info::munge_highspeed('15000000'), '15 Tbps', 'Tbps munge');
 | |
|   is(SNMP::Info::munge_highspeed('1500000'),
 | |
|     '1.5 Tbps', 'Fractional Tbps munge');
 | |
|   is(SNMP::Info::munge_highspeed('15000'), '15 Gbps',  'Gbps munge');
 | |
|   is(SNMP::Info::munge_highspeed('1500'),  '1.5 Gbps', 'Fractional Gbps munge');
 | |
|   is(SNMP::Info::munge_highspeed('100'),   '100 Mbps', 'Mbps munge');
 | |
| }
 | |
| 
 | |
| sub munge_ip : Tests(2) {
 | |
|   my $test = shift;
 | |
| 
 | |
|   can_ok($test->{info}, 'munge_ip');
 | |
|   my $test_ip = pack("C4", split /\./, "123.4.5.6");
 | |
|   is(SNMP::Info::munge_ip($test_ip),
 | |
|     "123.4.5.6", 'Binary IP to dotted ASCII munge');
 | |
| }
 | |
| 
 | |
| sub munge_mac : Tests(3) {
 | |
|   my $test = shift;
 | |
| 
 | |
|   can_ok($test->{info}, 'munge_mac');
 | |
| 
 | |
|   # The munge expects an octet string, pack a decimal string into
 | |
|   # representation munge is expecting
 | |
|   my $test_mac = pack("C*", split /\./, "01.35.69.103.137.171");
 | |
|   is(SNMP::Info::munge_mac($test_mac),
 | |
|     "01:23:45:67:89:ab", 'Octet string to colon separated ASCII hex string');
 | |
|   my $bogus_mac = pack("C*", split /\./, "01.35.69.103.137.171.02");
 | |
|   is(SNMP::Info::munge_mac($bogus_mac), undef,
 | |
|     'Bad octet string returns undef');
 | |
| }
 | |
| 
 | |
| sub munge_prio_mac : Tests(3) {
 | |
|   my $test = shift;
 | |
| 
 | |
|   can_ok($test->{info}, 'munge_prio_mac');
 | |
| 
 | |
|   # The munge expects an octet string, pack a decimal string into
 | |
|   # representation munge is expecting
 | |
|   my $test_mac = pack("C*", split /\./, "01.35.69.103.137.171.205.239");
 | |
|   is(SNMP::Info::munge_prio_mac($test_mac),
 | |
|     "01:23:45:67:89:ab:cd:ef",
 | |
|     'Octet string to colon separated ASCII hex string');
 | |
|   my $bogus_mac = pack("C*", split /\./, "01.35.69.103.137.171.205.239.02");
 | |
|   is(SNMP::Info::munge_prio_mac($bogus_mac),
 | |
|     undef, 'Bad octet string returns undef');
 | |
| }
 | |
| 
 | |
| sub munge_prio_port : Tests(3) {
 | |
|   my $test = shift;
 | |
| 
 | |
|   can_ok($test->{info}, 'munge_prio_port');
 | |
| 
 | |
|   # The munge expects an octet string, pack a decimal string into
 | |
|   # representation munge is expecting
 | |
|   my $test_mac = pack("C*", split /\./, "171.205");
 | |
|   is(SNMP::Info::munge_prio_port($test_mac),
 | |
|     "ab:cd", 'Octet string to colon separated ASCII hex string');
 | |
|   my $bogus_mac = pack("C*", split /\./, "171.205.02");
 | |
|   is(SNMP::Info::munge_prio_port($bogus_mac),
 | |
|     undef, 'Bad octet string returns undef');
 | |
| }
 | |
| 
 | |
| # Can't see where this code is actually used, remove?
 | |
| sub munge_octet2hex : Tests(2) {
 | |
|   my $test = shift;
 | |
| 
 | |
|   can_ok($test->{info}, 'munge_octet2hex');
 | |
| 
 | |
|   # The munge expects an octet string, pack a decimal string into
 | |
|   # representation munge is expecting
 | |
|   my $test_mac = pack("C*", split /\./, "171.205");
 | |
|   is(SNMP::Info::munge_octet2hex($test_mac),
 | |
|     "abcd", 'Octet string to ASCII hex string');
 | |
| }
 | |
| 
 | |
| sub munge_dec2bin : Tests(2) {
 | |
|   my $test = shift;
 | |
| 
 | |
|   can_ok($test->{info}, 'munge_dec2bin');
 | |
| 
 | |
|   # This is layers munge, use L3 test case
 | |
|   is(SNMP::Info::munge_dec2bin(4), '00000100', 'Binary char to ASCII binary');
 | |
| }
 | |
| 
 | |
| sub munge_bits : Tests(2) {
 | |
|   my $test = shift;
 | |
| 
 | |
|   can_ok($test->{info}, 'munge_bits');
 | |
| 
 | |
|   my $bits = pack("B*", '00010110');
 | |
| 
 | |
|   is(SNMP::Info::munge_bits($bits),
 | |
|     '00010110', 'SNMP2 BITS field to ASCII bit string');
 | |
| }
 | |
| 
 | |
| # TODO
 | |
| #sub munge_counter64 : Tests() {
 | |
| #  my $test = shift;
 | |
| #
 | |
| #}
 | |
| 
 | |
| sub munge_i_up : Tests(4) {
 | |
|   my $test = shift;
 | |
| 
 | |
|   can_ok($test->{info}, 'munge_i_up');
 | |
| 
 | |
|   is(SNMP::Info::munge_i_up(),  undef,            'No arg returns undef');
 | |
|   is(SNMP::Info::munge_i_up(4), 'unknown',        'Unknown status');
 | |
|   is(SNMP::Info::munge_i_up(7), 'lowerLayerDown', 'Lower layer down status');
 | |
| }
 | |
| 
 | |
| 1;
 |