Two new utilities added in t/util to assist in developing device support from snmpwalk output
This commit is contained in:
		
							
								
								
									
										207
									
								
								t/util/make_snmpdata.pl
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										207
									
								
								t/util/make_snmpdata.pl
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,207 @@ | ||||
| #!/usr/bin/perl | ||||
| # | ||||
| # make_snmpdata.pl | ||||
| # | ||||
| # Copyright (c) 2012 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. | ||||
|  | ||||
| use strict; | ||||
| use warnings; | ||||
| use Carp; | ||||
| use Getopt::Long; | ||||
| use Pod::Usage; | ||||
| use SNMP; | ||||
|  | ||||
| local $| = 1; | ||||
|  | ||||
| my $mibdirs = ['/usr/local/share/snmp/mibs']; | ||||
| my $comm    = 'public'; | ||||
| my $ver     = '2c'; | ||||
| my $dev; | ||||
| my $ignore = 0; | ||||
| my $help   = 0; | ||||
|  | ||||
| GetOptions( | ||||
|     'community=s' => \$comm, | ||||
|     'device=s'    => \$dev, | ||||
|     'ignore'      => \$ignore, | ||||
|     'mibdir=s'   => \$mibdirs, | ||||
|     'version'     => \$ver, | ||||
|     'help|?'      => sub { pod2usage(2); }, | ||||
| ) or pod2usage(2); | ||||
|  | ||||
| unless ( defined $dev && $ver =~ /[1|2c]/ ) { | ||||
|     pod2usage(1); | ||||
| } | ||||
|  | ||||
| local $ENV{'SNMPCONFPATH'} = ''        if $ignore; | ||||
| local $ENV{'MIBDIRS'}      = "$mibdirs" if $ignore; | ||||
|  | ||||
| SNMP::addMibDirs($mibdirs); | ||||
|  | ||||
| # Connect to Device | ||||
| my $sess = SNMP::Session->new( | ||||
|     'UseEnums'       => 1, | ||||
|     'RetryNoSuch'    => 1, | ||||
|     'DestHost'       => $dev, | ||||
|     'Community'      => $comm, | ||||
|     'Version'        => $ver, | ||||
|     'UseSprintValue' => 1 | ||||
| ); | ||||
|  | ||||
| my $sysdescr = $sess->get('sysDescr.0'); | ||||
| unless ( defined $sysdescr ) { | ||||
|     die "Couldn't connect to $dev via snmp.\n"; | ||||
| } | ||||
|  | ||||
| SNMP::loadModules(@ARGV); | ||||
|  | ||||
| # Create a hash of MIB Modules for which we want results  | ||||
| my %mib_hash = map {$_ => 1} @ARGV; | ||||
| # Add the common MIB Modules we always want | ||||
| my @common_mibs = ('SNMPv2-MIB', 'IF-MIB'); | ||||
| foreach my $mib (@common_mibs) { | ||||
|     $mib_hash{$mib} = 1; | ||||
| } | ||||
|  | ||||
| foreach my $key ( sort( keys %SNMP::MIB ) ) { | ||||
|     my $module = $SNMP::MIB{$key}{moduleID} || ''; | ||||
|     # IMPORTS pulls in many modules we don't want to walk | ||||
|     # Only walk those we've specified | ||||
|     next unless (defined $mib_hash{$module}); | ||||
|     my $access = $SNMP::MIB{$key}{'access'} || ''; | ||||
|     next unless ( $access =~ /Read|Create/x ); | ||||
|  | ||||
|     my $label = SNMP::translateObj( $key, 0, 1 ) || ''; | ||||
|     snmpwalk($label); | ||||
| } | ||||
|  | ||||
| sub snmpwalk { | ||||
|     return unless defined $sess; | ||||
|     my $label    = shift; | ||||
|     my $var      = SNMP::Varbind->new( [$label] ); | ||||
|     my $e        = 0; | ||||
|     my $last_iid = ''; | ||||
|     my %seen     = (); | ||||
|     while ( !$e ) { | ||||
|         $sess->getnext($var); | ||||
|         $e = $sess->{ErrorNum}; | ||||
|  | ||||
|         return if $var->[0] ne $label; | ||||
|         my $iid = $var->[1]; | ||||
|         my $val = $var->[2]; | ||||
|         return unless defined $iid; | ||||
|  | ||||
|         # Check to see if we've already seen this IID (looping) | ||||
|         if ( defined $seen{$iid} and $seen{$iid} ) { | ||||
|             warn "Looping on $label iid:$iid.  Skipped.\n"; | ||||
|             return; | ||||
|         } | ||||
|         else { $seen{$iid}++; } | ||||
|  | ||||
|         # why is it looping? | ||||
|         return if $last_iid eq $iid; | ||||
|         $last_iid = $iid; | ||||
|  | ||||
|         my $line = "$label.$iid = $val"; | ||||
|         print "$line\n"; | ||||
|     } | ||||
|     return; | ||||
| } | ||||
|  | ||||
| __END__ | ||||
|  | ||||
| =head1 NAME | ||||
|  | ||||
| make_snmpdata.pl - Tool to get SNMP data for the SNMP::Info testing framework | ||||
|  | ||||
| =head1 AUTHOR | ||||
|  | ||||
| Eric Miller | ||||
|  | ||||
| =head1 SYNOPSIS | ||||
|  | ||||
| make_snmpdata.pl [options] MIB-MODULE-1 MIB-MODULE-2 | ||||
|  | ||||
| Options: | ||||
|  | ||||
|     -community SNMP Community | ||||
|     -device    IP Address to query | ||||
|     -ignore    Ignore Net-SNMP configuration file | ||||
|     -mibdir    Directory containing MIB Files | ||||
|     -version   SNMP version to use | ||||
|     -help      Brief help message | ||||
|  | ||||
| =head1 OPTIONS | ||||
|  | ||||
| =over 8 | ||||
|  | ||||
| =item B<-community> | ||||
|  | ||||
| SNMP Community, either 1 or 2c.  Defaults to version 2c | ||||
|  | ||||
| -community 2c | ||||
|  | ||||
| =item B<-device> | ||||
|  | ||||
| IP Address to query for the SNMP data.  No default and a mandatory option. | ||||
|  | ||||
| -device 127.0.0.1 | ||||
|  | ||||
| =item B<-ignore > | ||||
|  | ||||
| Ignore Net-SNMP configuration file snmp.conf.  If this used mibdirs must be | ||||
| provided | ||||
|  | ||||
| -ignore | ||||
|  | ||||
| =item B<-mibdir> | ||||
|  | ||||
| Directory containing MIB Files.  Mutiple directories should be separated by a | ||||
| colon ':'.  Defaults to /usr/local/share/snmp/mibs. | ||||
|  | ||||
| -mibdir /usr/local/share/snmp/mibs/rfc:/usr/local/share/snmp/mibs/net-snmp | ||||
|  | ||||
| =item B<-version> | ||||
|  | ||||
| SNMP version to use.  Only version 1 and 2c are supported.  Defaults to 2c | ||||
|  | ||||
| -version 2c | ||||
|  | ||||
| =item B<-help> | ||||
|  | ||||
| Print help message and exits. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head1 DESCRIPTION | ||||
|  | ||||
| B<make_snmpdata.pl> will gather SNMP data by walking specified MIB files and | ||||
| output the data to a file which can be used by the SNMP::Info testing | ||||
| framework. | ||||
|  | ||||
| =cut | ||||
							
								
								
									
										453
									
								
								t/util/test_class_mocked.pl
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										453
									
								
								t/util/test_class_mocked.pl
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,453 @@ | ||||
| #!/usr/bin/perl | ||||
| # | ||||
| # test_class_mocked.pl | ||||
| # | ||||
| # Copyright (c) 2012 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. | ||||
|  | ||||
| use strict; | ||||
| use warnings; | ||||
| use Carp; | ||||
| use FindBin; | ||||
| use lib "$FindBin::Bin/../../.."; | ||||
| use File::Slurp qw(slurp); | ||||
| use Getopt::Long; | ||||
| use Pod::Usage; | ||||
| use SNMP::Info; | ||||
| use Test::MockObject::Extends; | ||||
|  | ||||
| my $EMPTY = q{}; | ||||
|  | ||||
| # Default Values | ||||
| my $class = $EMPTY; | ||||
| my @dump  = (); | ||||
| my $debug = 0; | ||||
| my $mibdirs; | ||||
| my $ignore = 0; | ||||
| my $help   = 0; | ||||
| my $file; | ||||
| my %dumped; | ||||
|  | ||||
| GetOptions( | ||||
|     'c|class=s'  => \$class, | ||||
|     'i|ignore'   => \$ignore, | ||||
|     'p|print=s'  => \@dump, | ||||
|     'x|debug+'   => \$debug, | ||||
|     'm|mibdir=s' => \$mibdirs, | ||||
|     'file=s'     => \$file, | ||||
|     'h|?|help'   => sub { pod2usage(1); }, | ||||
| ); | ||||
|  | ||||
| if ( !$file ) { | ||||
|     pod2usage(1); | ||||
| } | ||||
|  | ||||
| if ( $ignore && !defined $mibdirs ) { | ||||
|     print "mibdirs must be provided if ignoring snmp.conf \n\n"; | ||||
|     pod2usage(1); | ||||
| } | ||||
|  | ||||
| if ($ignore) { local $ENV{'SNMPCONFPATH'} = $EMPTY } | ||||
| if ($ignore) { local $ENV{'MIBDIRS'}      = "$mibdirs" } | ||||
|  | ||||
| if ( defined $mibdirs ) { | ||||
|     SNMP::addMibDirs($mibdirs); | ||||
| } | ||||
|  | ||||
| $class = $class ? "SNMP::Info::$class" : 'SNMP::Info'; | ||||
|  | ||||
| ( my $mod = "$class.pm" ) | ||||
|     =~ s{::}{/}g;    # SNMP::Info::Layer3 => SNMP/Info/Layer3.pm | ||||
| if ( !eval { require $mod; 1; } ) { | ||||
|     croak "Could not load $class. Error Message: $@\n"; | ||||
| } | ||||
|  | ||||
| my $class_ver = $class->VERSION(); | ||||
|  | ||||
| print | ||||
|     "Class $class ($class_ver) loaded from SNMP::Info $SNMP::Info::VERSION.\n"; | ||||
|  | ||||
| if ( scalar @dump ) { print 'Dumping : ', join( q{,}, @dump ), "\n" } | ||||
|  | ||||
| my $mocked = create_mock_session(); | ||||
|  | ||||
| my $dev = $class->new( | ||||
|     'AutoSpecify' => 0, | ||||
|     'BulkWalk'    => 0, | ||||
|     'Debug'       => $debug, | ||||
|     'MibDirs'     => $mibdirs, | ||||
|     'Session'     => $mocked, | ||||
| ) or die "\n"; | ||||
|  | ||||
| print 'Detected Class: ', $dev->device_type(), "\n"; | ||||
| print "Using    Class: $class (-c to change)\n"; | ||||
|  | ||||
| my $layers = $dev->layers(); | ||||
| my $descr  = $dev->description(); | ||||
|  | ||||
| if ( !defined $layers || !defined $descr ) { | ||||
|     die "Are you sure you specified a file created with make_snmpdata.pl ?\n"; | ||||
| } | ||||
|  | ||||
| print "\nFetching base info...\n\n"; | ||||
|  | ||||
| my @base_fns = qw/vendor model os os_ver description contact location | ||||
|     layers mac serial/; | ||||
|  | ||||
| foreach my $fn (@base_fns) { | ||||
|     test_global( $dev, $fn ); | ||||
| } | ||||
|  | ||||
| print "\nFetching interface info...\n\n"; | ||||
|  | ||||
| my @fns = qw/interfaces i_type i_ignore i_description i_mtu i_speed i_mac i_up | ||||
|     i_up_admin i_name i_duplex i_duplex_admin i_stp_state | ||||
|     i_vlan i_pvid i_lastchange/; | ||||
|  | ||||
| foreach my $fn (@fns) { | ||||
|     test_fn( $dev, $fn ); | ||||
| } | ||||
|  | ||||
| print "\nFetching VLAN info...\n\n"; | ||||
|  | ||||
| my @vlan = qw/v_index v_name/; | ||||
|  | ||||
| foreach my $fn (@vlan) { | ||||
|     test_fn( $dev, $fn ); | ||||
| } | ||||
|  | ||||
| print "\nFetching topology info...\n\n"; | ||||
|  | ||||
| my @topo = qw/c_if c_ip c_port/; | ||||
|  | ||||
| foreach my $fn (@topo) { | ||||
|     test_fn( $dev, $fn ); | ||||
| } | ||||
|  | ||||
| print "\nFetching module info...\n\n"; | ||||
|  | ||||
| my @modules = qw/e_descr e_type e_parent e_name e_class e_pos e_hwver | ||||
|                 e_fwver e_swver e_model e_serial e_fru/; | ||||
|  | ||||
| foreach my $fn (@modules) { | ||||
|     test_fn( $dev, $fn ); | ||||
| } | ||||
|  | ||||
| foreach my $fn (@dump) { | ||||
|     if ( !$dumped{$fn} ) { test_fn( $dev, $fn ) } | ||||
| } | ||||
|  | ||||
| #-------------------------------- | ||||
|  | ||||
| sub load_snmpdata { | ||||
|     my $data_file = shift; | ||||
|  | ||||
|     my @lines = slurp($data_file); | ||||
|  | ||||
|     my $snmp_data = {}; | ||||
|     foreach my $line (@lines) { | ||||
| 	next if !$line; | ||||
| 	next if ( $line =~ /^#/ ); | ||||
| 	if ( $line =~ /^(\S+::\w+)[.]?(\S+)*\s=\s(.*)$/ ) { | ||||
| 	    my ( $leaf, $iid, $val ) = ( $1, $2, $3 ); | ||||
| 	    next if !$leaf; | ||||
| 	    $iid ||= 0; | ||||
| 	    $val =~ s/\"//g; | ||||
| 	    $snmp_data->{$leaf}->{$iid} = $val; | ||||
| 	} | ||||
|     } | ||||
|     return $snmp_data; | ||||
| } | ||||
|  | ||||
| sub create_mock_session { | ||||
|  | ||||
|     my $snmp_data = load_snmpdata($file); | ||||
|  | ||||
|     my $session = SNMP::Session->new( | ||||
| 	UseEnums    => 1, | ||||
| 	RetryNoSuch => 1, | ||||
| 	Data        => $snmp_data, | ||||
| 	DestHost    => '127.0.0.1', | ||||
| 	Community   => 'public', | ||||
| 	Version     => 2, | ||||
|     ); | ||||
|  | ||||
|     my $mock_session = Test::MockObject::Extends->new($session); | ||||
|  | ||||
|     mock_get($mock_session); | ||||
|     mock_getnext($mock_session); | ||||
|  | ||||
|     return $mock_session; | ||||
| } | ||||
|  | ||||
| sub mock_get { | ||||
|     my $mock_session = shift; | ||||
|  | ||||
|     $mock_session->mock( | ||||
| 	'get', | ||||
| 	sub { | ||||
| 	    my $self = shift; | ||||
| 	    my $vars = shift; | ||||
| 	    my ( $leaf, $iid, $oid, $oid_name ); | ||||
| 	    my $c_data = $self->{Data}; | ||||
|  | ||||
| 	    # From SNMP::Info get will only be passed either an OID or | ||||
| 	    # SNMP::Varbind with a fully qualified leaf and potentially | ||||
| 	    # a partial | ||||
| 	    if ( ref($vars) =~ /SNMP::Varbind/ ) { | ||||
| 		( $leaf, $iid ) = @{$vars}; | ||||
| 	    } | ||||
| 	    else { | ||||
| 		$oid = $vars; | ||||
| 		$oid_name = SNMP::translateObj( $oid, 0, 1 ) || $EMPTY; | ||||
| 		( $leaf, $iid ) = $oid_name =~ /^(\S+::\w+)[.]?(\S+)*$/; | ||||
| 	    } | ||||
|  | ||||
| 	    $iid ||= 0; | ||||
| 	    my $new_iid = $iid; | ||||
| 	    my $val     = $EMPTY; | ||||
| 	    my $data    = $c_data->{$leaf} || {}; | ||||
| 	    my $count   = scalar keys %{$data} || 0; | ||||
| 	    if ( $count > 1 ) { | ||||
| 		my $found = 0; | ||||
| 		foreach my $d_iid ( sort keys %{$data} ) { | ||||
| 		    if ( $d_iid eq $iid ) { | ||||
| 			$val   = $data->{$d_iid}; | ||||
| 			$found = 1; | ||||
| 			next; | ||||
| 		    } | ||||
| 		    elsif ( $found == 1 ) { | ||||
| 			$new_iid = $d_iid; | ||||
| 			last; | ||||
| 		    } | ||||
| 		} | ||||
| 		if ( $found && ( $new_iid eq $iid ) ) { | ||||
| 		    $leaf = 'unknown'; | ||||
| 		} | ||||
| 	    } | ||||
| 	    else { | ||||
| 		$val  = $data->{$iid}; | ||||
| 		$leaf = 'unknown'; | ||||
| 	    } | ||||
|  | ||||
| 	    if ( ref $vars =~ /SNMP::Varbind/ ) { | ||||
| 		$vars->[0] = $leaf; | ||||
| 		$vars->[1] = $new_iid; | ||||
| 		$vars->[2] = $val; | ||||
| 	    } | ||||
| 	    return ( wantarray() ? $vars : $val ); | ||||
| 	} | ||||
|     ); | ||||
|     return; | ||||
| } | ||||
|  | ||||
| sub mock_getnext { | ||||
|     my $mock_session = shift; | ||||
|  | ||||
|     $mock_session->mock( | ||||
| 	'getnext', | ||||
| 	sub { | ||||
| 	    my $self = shift; | ||||
| 	    my $vars = shift; | ||||
| 	    my ( $leaf, $iid, $oid, $oid_name ); | ||||
| 	    my $c_data = $self->{Data}; | ||||
|  | ||||
| 	    # From SNMP::Info getnext will only be passed a SNMP::Varbind | ||||
| 	    # with a fully qualified leaf and potentially a partial | ||||
| 	    ( $leaf, $iid ) = @{$vars}; | ||||
|  | ||||
| 	    $iid ||= 0; | ||||
| 	    my $new_iid = $iid; | ||||
| 	    my $val     = $EMPTY; | ||||
| 	    my $data    = $c_data->{$leaf}; | ||||
| 	    my $count   = scalar keys %{$data} || 0; | ||||
| 	    if ( $count > 1 ) { | ||||
| 		my $found = 0; | ||||
| 		foreach my $d_iid ( sort keys %{$data} ) { | ||||
| 		    if ( $d_iid gt $iid && !$found ) { | ||||
| 			$val     = $data->{$d_iid}; | ||||
| 			$new_iid = $d_iid; | ||||
| 			$found   = 1; | ||||
| 			next; | ||||
| 		    } | ||||
| 		    elsif ( $found == 1 ) { | ||||
| 			last; | ||||
| 		    } | ||||
| 		} | ||||
| 		if ( $found && ( $new_iid eq $iid ) ) { | ||||
| 		    $leaf = 'unknown'; | ||||
| 		} | ||||
| 	    } | ||||
| 	    else { | ||||
| 		$val  = $data->{$iid}; | ||||
| 		$leaf = 'unknown'; | ||||
| 	    } | ||||
|  | ||||
| 	    $vars->[0] = $leaf; | ||||
| 	    $vars->[1] = $new_iid; | ||||
| 	    $vars->[2] = $val; | ||||
| 	    return ( wantarray() ? $vars : $val ); | ||||
| 	} | ||||
|     ); | ||||
|     return; | ||||
| } | ||||
|  | ||||
| sub test_global { | ||||
|     my $device = shift; | ||||
|     my $method = shift; | ||||
|  | ||||
|     my $value = $device->$method(); | ||||
|  | ||||
|     if ( !defined $value ) { | ||||
| 	printf "%-20s Does not exist.\n", $method; | ||||
| 	return 0; | ||||
|     } | ||||
|     $value =~ s/[[:cntrl:]]+/ /g; | ||||
|     if ( length $value > 60 ) { | ||||
| 	$value = substr $value, 0, 60; | ||||
| 	$value .= '...'; | ||||
|     } | ||||
|     printf "%-20s %s \n", $method, $value; | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| sub test_fn { | ||||
|     my $device = shift; | ||||
|     my $method = shift; | ||||
|  | ||||
|     my $results = $device->$method(); | ||||
|  | ||||
|     # If accidentally called on a global, pass it along nicely. | ||||
|     if ( defined $results && !ref $results ) { | ||||
| 	return test_global( $dev, $method ); | ||||
|     } | ||||
|     if ( !defined $results && !scalar keys %{$results} ) { | ||||
| 	printf "%-20s Empty Results.\n", $method; | ||||
| 	return 0; | ||||
|     } | ||||
|  | ||||
|     printf "%-20s %d rows.\n", $method, scalar keys %{$results}; | ||||
|     if ( grep {/^$method$/} @dump ) { | ||||
| 	$dumped{$method} = 1; | ||||
| 	foreach my $iid ( keys %{$results} ) { | ||||
| 	    print "  $iid : "; | ||||
| 	    if ( ref( $results->{$iid} ) eq 'ARRAY' ) { | ||||
| 		print '[ ', join( ', ', @{ $results->{$iid} } ), ' ]'; | ||||
| 	    } | ||||
| 	    else { | ||||
| 		print $results->{$iid}; | ||||
| 	    } | ||||
| 	    print "\n"; | ||||
| 	} | ||||
|     } | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| __END__ | ||||
|  | ||||
| =head1 NAME | ||||
|  | ||||
| test_class_mocked.pl - Test a device against an SNMP::Info class using | ||||
| output from make_snmpdata.pl stored in a text file. | ||||
|  | ||||
| =head1 AUTHOR | ||||
|  | ||||
| Eric Miller | ||||
|  | ||||
| =head1 SYNOPSIS | ||||
|  | ||||
| test_class_mocked.pl [options] | ||||
|  | ||||
| Options: | ||||
|  | ||||
|     -class    SNMP::Info class to use, Layer2::Catalyst     | ||||
|     -file     File containing data gathered using make_snmpdata.pl | ||||
|     -print    Print values  | ||||
|     -debug    Debugging flag | ||||
|     -ignore   Ignore Net-SNMP configuration file | ||||
|     -mibdir   Directory containing MIB Files | ||||
|     -help     Brief help message | ||||
|  | ||||
| =head1 OPTIONS | ||||
|  | ||||
| =over 8 | ||||
|  | ||||
| =item B<-class> | ||||
|  | ||||
| Specific SNMP::Info class to use.  Defaults to SNMP::Info if no specific | ||||
| class provided. | ||||
|  | ||||
| -class Layer2::Catalyst | ||||
|  | ||||
| =item B<-file> | ||||
|  | ||||
| File containing data gathered using make_snmpdata.pl.  No default and a | ||||
| mandatory option. | ||||
|  | ||||
| -file /data/mydevice.txt | ||||
|  | ||||
| =item B<-print> | ||||
|  | ||||
| Print values of a class method rather than summarizing.  May be repeated | ||||
| multiple times.  | ||||
|  | ||||
| -print i_description -print i_type | ||||
|  | ||||
| =item B<-debug> | ||||
|  | ||||
| Turns on SNMP::Info debug. | ||||
|  | ||||
| -debug | ||||
|  | ||||
| =item B<-ignore > | ||||
|  | ||||
| Ignore Net-SNMP configuration file snmp.conf.  If this used mibdirs must be | ||||
| provided. | ||||
|  | ||||
| -ignore | ||||
|  | ||||
| =item B<-mibdir> | ||||
|  | ||||
| Directory containing MIB Files.  Multiple directories should be separated by a | ||||
| colon ':'.  | ||||
|  | ||||
| -mibdir /usr/local/share/snmp/mibs/rfc:/usr/local/share/snmp/mibs/net-snmp | ||||
|  | ||||
| =item B<-help> | ||||
|  | ||||
| Print help message and exits. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head1 DESCRIPTION | ||||
|  | ||||
| B<test_class_mocked.pl> will test a device against an SNMP::Info class using | ||||
| snmpwalk output from the utility B<make_snmpdata.pl> stored in a text file. | ||||
| This allows debugging and testing without requiring network access to the | ||||
| device being tested. | ||||
|  | ||||
| =cut | ||||
		Reference in New Issue
	
	Block a user