# Test::SNMP::Info::Layer3::Juniper # # 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 Test::SNMP::Info::Layer3::Juniper; use Test::Class::Most parent => 'My::Test::Class'; use SNMP::Info::Layer3::Juniper; sub setup : Tests(setup) { my $test = shift; $test->SUPER::setup; # Start with a common cache that will serve most tests my $d_string = 'Juniper Networks, Inc. ex4200-24t internet router, '; $d_string .= 'kernel JUNOS 10.4R6.5 '; my $cache_data = { '_layers' => 6, '_description' => $d_string, # JUNIPER-CHASSIS-DEFINES-MIB::jnxProductNameEX4200 '_id' => '.1.3.6.1.4.1.2636.1.1.1.2.31', '_version' => '14.1X53-D40.8', '_serial' => 'AB0123456789', '_jnxExVlanPortAccessMode' => 1, '_jnx_v_name' => 1, '_jnx_v_index' => 1, '_jnx_v_type' => 1, # Newer table doesn't exist in EX4200, but in cache to simplify testing # method code '_jnx_els_v_name' => 1, '_jnx_els_v_index' => 1, '_jnx_els_v_type' => 1, '_jnx_els_v_fdb_id' => 1, '_bp_index' => 1, '_qb_i_vlan' => 1, '_qb_v_egress' => 1, '_qb_v_untagged' => 1, '_qb_fw_port' => 1, # For pseudo entity testing '_box_descr' => 'Juniper Virtual Chassis Ethernet Switch', '_jnxVirtualChassisMemberRole' => 'master', '_jnxContainersWithin' => 1, '_jnxContentsDescr' => 1, '_jnxContentsSerialNo' => 1, '_jnxFruType' => 1, '_jnxContainersDescr' => 1, '_e_containers_type' => 1, '_jnxContentsPartNo' => 1, '_e_contents_type' => 1, '_jnxContainersWithin' => 1, 'store' => { 'jnxExVlanPortAccessMode' => {'2.514' => 'access', '7.513' => 'trunk'}, 'jnx_v_name' => {2 => 'default', 3 => 'management'}, 'jnx_v_index' => {2 => 0, 3 => 120}, 'jnx_v_type' => {2 => 'static', 3 => 'static'}, # Newer table doesn't exist in EX4200, but in cache to simplify testing # method code 'jnx_els_v_name' => {6 => 'VLAN0114_VPN78087', 7 => 'VLAN2088_VPN78117', 8 => 'default'}, 'jnx_els_v_index' => {6 => 114, 7 => 2088, 8 => 1}, 'jnx_els_v_type' => {6 => 'static', 7 => 'static', 8 => 'static'}, 'jnx_els_v_fdb_id' => {6 => 393216, 7 => 458752, 8 => 524288}, 'bp_index' => {4 => 662, 491 => 509, 492 => 510}, 'qb_i_vlan' => {4 => 0, 491 => 113, 492 => 2088}, 'qb_v_egress' => {114 => '4', 2088 => '491,492'}, 'qb_v_untagged' => {114 => '4', 2088 => '491,492'}, 'qb_fw_port' => {'393216.0.19.149.30.221.37' => 4, '458752.0.9.245.16.59.121' => 492}, 'jnxContainersWithin' => {1 => 0, 2 => 1, 4 => 1, 7 => 1, 8 => 7, 9 => 1}, 'jnxContentsDescr' => { '1.1.0.0' => '', '2.1.1.0' => 'Power Supply: Power Supply 0 @ 0/0/*', '2.1.2.0' => 'Power Supply: Power Supply 1 @ 0/1/*', '2.2.1.0' => 'Power Supply: Power Supply 0 @ 1/0/*', '2.2.2.0' => 'Power Supply: Power Supply 1 @ 1/1/*', '4.1.1.1' => 'FAN 0 @ 0/0/0', '4.1.2.1' => 'FAN 1 @ 0/1/0', '4.2.1.1' => 'FAN 0 @ 1/0/0', '4.2.2.1' => 'FAN 1 @ 1/1/0', '7.1.0.0' => 'FPC: EX4300-48T @ 0/*/*', '7.2.0.0' => 'FPC: EX4300-48T @ 1/*/*', '8.1.1.0' => 'PIC: 48x 10/100/1000 Base-T @ 0/0/*', '8.1.2.0' => 'PIC: 4x 40GE QSFP+ @ 0/1/*', '8.1.3.0' => 'PIC: 4x 1G/10G SFP/SFP+ @ 0/2/*', '8.2.1.0' => 'PIC: 48x 10/100/1000 Base-T @ 1/0/*', '8.2.2.0' => 'PIC: 4x 40GE QSFP+ @ 1/1/*', '8.2.3.0' => 'PIC: 4x 1G/10G SFP/SFP+ @ 1/2/*', '9.1.0.0' => 'Routing Engine 0', '9.2.0.0' => 'Routing Engine 1' }, 'jnxContentsSerialNo' => { '2.1.1.0' => '1EDD1234567', '2.1.2.0' => '1EDD2345678', '2.2.1.0' => '1EDD3456789', '2.2.2.0' => '1EDD4567890', '7.1.0.0' => 'PE1234567890', '7.2.0.0' => 'PE0123456789', '8.1.1.0' => 'BUILTIN', '8.1.2.0' => 'BUILTIN', '8.1.3.0' => 'MY1234567890', '8.2.1.0' => 'BUILTIN', '8.2.2.0' => 'BUILTIN', '8.2.3.0' => 'MY0123456789', '9.1.0.0' => 'PE2345678901', '9.2.0.0' => 'PE3456789012' }, 'jnxFruType' => { '2.1.1.0' => 'powerEntryModule', '2.1.2.0' => 'powerEntryModule', '2.2.1.0' => 'powerEntryModule', '2.2.2.0' => 'powerEntryModule', '4.1.1.1' => 'fan', '4.1.2.1' => 'fan', '4.2.1.1' => 'fan', '4.2.2.1' => 'fan', '7.1.0.0' => 'flexiblePicConcentrator', '7.2.0.0' => 'flexiblePicConcentrator', '8.1.1.0' => 'portInterfaceCard', '8.1.2.0' => 'portInterfaceCard', '8.1.3.0' => 'portInterfaceCard', '8.2.1.0' => 'portInterfaceCard', '8.2.2.0' => 'portInterfaceCard', '8.2.3.0' => 'portInterfaceCard', '9.1.0.0' => 'routingEngine', '9.2.0.0' => 'routingEngine' }, 'jnxContentsPartNo' => { '2.1.1.0' => '740-046876', '2.1.2.0' => '740-046876', '2.2.1.0' => '740-046876', '2.2.2.0' => '740-046876', '7.1.0.0' => '650-044932', '7.2.0.0' => '650-044932', '8.1.1.0' => 'BUILTIN', '8.1.2.0' => 'BUILTIN', '8.1.3.0' => '611-063980', '8.2.1.0' => 'BUILTIN', '8.2.2.0' => 'BUILTIN', '8.2.3.0' => '611-063980', '9.1.0.0' => '650-044932', '9.2.0.0' => '650-044932' }, # These are cached raw 'e_contents_type' => { '1.1.0.0' => '.1.3.6.1.4.1.2636.1.1.2.1.63.0', '2.1.1.0' => '.1.3.6.1.4.1.2636.1.1.3.2.63.1.1.0', '2.1.2.0' => '.1.3.6.1.4.1.2636.1.1.3.2.63.1.1.0', '2.2.1.0' => '.1.3.6.1.4.1.2636.1.1.3.2.63.1.1.0', '2.2.2.0' => '.1.3.6.1.4.1.2636.1.1.3.2.63.1.1.0', '4.1.1.1' => '.1.3.6.1.4.1.2636.1.1.3.2.63.1.2.0', '4.1.2.1' => '.1.3.6.1.4.1.2636.1.1.3.2.63.1.2.0', '4.2.1.1' => '.1.3.6.1.4.1.2636.1.1.3.2.63.1.2.0', '4.2.2.1' => '.1.3.6.1.4.1.2636.1.1.3.2.63.1.2.0', '7.1.0.0' => '.1.3.6.1.4.1.2636.1.1.3.2.63.1.0', '7.2.0.0' => '.1.3.6.1.4.1.2636.1.1.3.2.63.1.0', '8.1.1.0' => '.1.3.6.1.4.1.2636.1.1.1.4.63.2.0', '8.1.2.0' => '.1.3.6.1.4.1.2636.1.1.3.3.12.1.319.0', '8.1.3.0' => '.1.3.6.1.4.1.2636.1.1.3.3.12.1.320.0', '8.2.1.0' => '.1.3.6.1.4.1.2636.1.1.1.4.63.2.0', '8.2.2.0' => '.1.3.6.1.4.1.2636.1.1.3.3.12.1.319.0', '8.2.3.0' => '.1.3.6.1.4.1.2636.1.1.3.3.12.1.320.0', '9.1.0.0' => '.1.3.6.1.4.1.2636.1.1.2.1.63.1.0', '9.2.0.0' => '.1.3.6.1.4.1.2636.1.1.2.1.63.1.0' }, 'jnxContainersDescr' => { 1 => 'chassis frame', 2 => 'Power Supply slot', 4 => 'FAN slot', 7 => 'FPC slot', 8 => 'PIC slot', 9 => 'Routing Engine slot' }, # These are cached raw 'e_containers_type' => { 1 => '.1.3.6.1.4.1.2636.1.1.2.1.63.0', 2 => '.1.3.6.1.4.1.2636.1.1.2.2.63.1.1.0', 4 => '.1.3.6.1.4.1.2636.1.1.2.2.63.1.2.0', 7 => '.1.3.6.1.4.1.2636.1.1.2.2.63.1.0', 8 => '.1.3.6.1.4.1.2636.1.1.2.3.63.1.0', 9 => '.1.3.6.1.4.1.2636.1.1.2.1.63.1.0' }, 'jnxContainersWithin' => {1 => 0, 2 => 1, 4 => 1, 7 => 1, 8 => 7, 9 => 1} } }; $test->{info}->cache($cache_data); } sub vendor : Tests(2) { my $test = shift; can_ok($test->{info}, 'vendor'); is($test->{info}->vendor(), 'juniper', q(Vendor returns 'juniper')); } sub os : Tests(2) { my $test = shift; can_ok($test->{info}, 'os'); is($test->{info}->os(), 'junos', q(OS returns 'junos')); } sub layers : Tests(5) { my $test = shift; can_ok($test->{info}, 'layers'); is($test->{info}->layers(), '00000110', q(Original layers unmodified)); # Set to layer 3 only and with presence of FDB 'qb_fw_port' will turn on # layer 2 $test->{info}{_layers} = 4; is($test->{info}->layers(), '00000110', q(Layer2 added due to presence of FDB)); # Delete FDB cache flag, layers still = 4 binary (3 only) delete $test->{info}{_qb_fw_port}; is($test->{info}->layers(), '00000100', q(No layer2 without FDB)); $test->{info}->clear_cache(); is($test->{info}->layers(), undef, q(No data returns undef layers)); } sub os_ver : Tests(5) { my $test = shift; can_ok($test->{info}, 'os_ver'); is($test->{info}->os_ver(), '14.1X53-D40.8', q(OS version returned from 'jnxVirtualChassisMemberSWVersion')); delete $test->{info}{_version}; is($test->{info}->os_ver(), '10.4R6.5', q(OS version returned from 'sysDescr')); delete $test->{info}{_description}; $test->{info}{_lldp_sysdesc} = 'Juniper Networks, Inc. srx240h-poe , version 12.1R3.5 Build date: '; is($test->{info}->os_ver(), '12.1R3.5', q(OS version returned from 'lldpLocSysDesc')); $test->{info}->clear_cache(); is($test->{info}->os_ver(), undef, q(No data returns undef OS version)); } sub model : Tests(4) { my $test = shift; can_ok($test->{info}, 'model'); is($test->{info}->model(), 'EX4200', q(Model translates id)); $test->{info}{_id} = '.100.3.6.1.4.1.6527.1.3.1'; is($test->{info}->model(), '.100.3.6.1.4.1.6527.1.3.1', q(Model uses id)); $test->{info}{_vc_model} = 'qfx5100-48s-6q'; is($test->{info}->model(), 'QFX5100-48S-6Q', q(Model uses 'jnxVirtualChassisMemberModel')); } sub serial : Tests(3) { my $test = shift; can_ok($test->{info}, 'serial'); is($test->{info}->serial(), 'AB0123456789', q(Serial returns 'jnxBoxSerialNo')); $test->{info}->clear_cache(); is($test->{info}->serial(), undef, q(No data returns undef serial)); } sub i_trunk : Tests(3) { my $test = shift; can_ok($test->{info}, 'i_trunk'); my $expected = {'514' => 'access', '513' => 'trunk'}; cmp_deeply($test->{info}->i_trunk(), $expected, q(Interface trunk status returns expected values)); $test->{info}->clear_cache(); cmp_deeply($test->{info}->i_trunk(), {}, q(No data returns empty hash)); } sub qb_fdb_index : Tests(4) { my $test = shift; can_ok($test->{info}, 'qb_fdb_index'); my $expected = {393216 => 114, 458752 => 2088, 524288 => 1}; cmp_deeply($test->{info}->qb_fdb_index(), $expected, q(ELS VLAN to FDB index returned expected values)); delete $test->{info}{'_jnx_els_v_index'}; $expected = {2 => 0, 3 => 120}; cmp_deeply($test->{info}->qb_fdb_index(), $expected, q(Older VLAN to FDB index returned expected values)); $test->{info}->clear_cache(); cmp_deeply($test->{info}->qb_fdb_index(), undef, q(No data returns undef)); } sub v_type : Tests(4) { my $test = shift; can_ok($test->{info}, 'v_type'); my $expected = {6 => 'static', 7 => 'static', 8 => 'static'}; cmp_deeply($test->{info}->v_type(), $expected, q(ELS VLAN types returned expected values)); delete $test->{info}{'_jnx_els_v_type'}; $expected = {2 => 'static', 3 => 'static'}; cmp_deeply($test->{info}->v_type(), $expected, q(Older VLAN types returned expected values)); $test->{info}->clear_cache(); cmp_deeply($test->{info}->v_type(), undef, q(No data returns undef)); } sub v_index : Tests(4) { my $test = shift; can_ok($test->{info}, 'v_index'); my $expected = {6 => 114, 7 => 2088, 8 => 1}; cmp_deeply($test->{info}->v_index(), $expected, q(ELS VLAN index returned expected values)); delete $test->{info}{'_jnx_els_v_index'}; $expected = {2 => 0, 3 => 120}; cmp_deeply($test->{info}->v_index(), $expected, q(Older VLAN index returned expected values)); $test->{info}->clear_cache(); cmp_deeply($test->{info}->v_index(), undef, q(No data returns undef)); } sub i_vlan : Tests(4) { my $test = shift; can_ok($test->{info}, 'i_vlan'); my $expected = {662 => 0, 509 => 113, 510 => 2088}; cmp_deeply($test->{info}->i_vlan(), $expected, q(ELS PVID returned expected values)); delete $test->{info}{'_jnx_els_v_index'}; $test->{info}{store}{bp_index} = {513 => 505, 514 => 507}; $test->{info}{store}{qb_i_vlan} = {513 => 3, 514 => 2}; $expected = {505 => 120, 507 => 0}; cmp_deeply($test->{info}->i_vlan(), $expected, q(Older PVID returned expected values)); $test->{info}->clear_cache(); cmp_deeply($test->{info}->i_vlan(), {}, q(No data returns empty hash)); } sub v_name : Tests(4) { my $test = shift; can_ok($test->{info}, 'v_name'); my $expected = {6 => 'VLAN0114_VPN78087', 7 => 'VLAN2088_VPN78117', 8 => 'default'}; cmp_deeply($test->{info}->v_name(), $expected, q(ELS VLAN names returned expected values)); delete $test->{info}{'_jnx_els_v_name'}; $expected = {2 => 'default', 3 => 'management'}; cmp_deeply($test->{info}->v_name(), $expected, q(Older VLAN names returned expected values)); $test->{info}->clear_cache(); cmp_deeply($test->{info}->v_name(), undef, q(No data returns undef)); } sub i_vlan_membership : Tests(4) { my $test = shift; can_ok($test->{info}, 'i_vlan_membership'); # Delete this so we can test new method first delete $test->{info}{'_jnx_v_index'}; my $expected = {662 => [114], 509 => [2088], 510 => [2088]}; cmp_deeply($test->{info}->i_vlan_membership(), $expected, q(ELS VLAN membership returned expected values)); # Restore so we can trigger test for older devices $test->{info}{'_jnx_v_index'} = 1; delete $test->{info}{'_jnx_els_v_index'}; my $padding = '00000000000000000000000000000000' x 4; # This has bits 516 - 536 on my $portlist2 = $padding . '1FFFFF'; # This has bits 512 - 515 on my $portlist3 = $padding . 'E0'; # To simplify the expected value, we're only going to define the mapping # for five ports $test->{info}{store}{bp_index} = {513 => 505, 514 => 507, 515 => 509, 516 => 511, 536 => 551}; $test->{info}{store}{qb_v_egress} = {2 => pack("H*", $portlist2), 3 => pack("H*", $portlist3)}; $expected = {505 => [120], 507 => [120], 509 => [120], 511 => [0], 551 => [0]}; cmp_deeply($test->{info}->i_vlan_membership(), $expected, q(VLAN membership returned expected values)); $test->{info}->clear_cache(); cmp_deeply($test->{info}->i_vlan_membership(), undef, q(No data returns undef)); } # Same code as i_vlan_membership, untagged just uses different leaf sub i_vlan_membership_untagged : Tests(4) { my $test = shift; can_ok($test->{info}, 'i_vlan_membership_untagged'); # Delete this so we can test new method first delete $test->{info}{'_jnx_v_index'}; my $expected = {662 => [114], 509 => [2088], 510 => [2088]}; cmp_deeply($test->{info}->i_vlan_membership_untagged(), $expected, q(ELS VLAN membership untagged returned expected values)); # Restore so we can trigger test for older devices $test->{info}{'_jnx_v_index'} = 1; delete $test->{info}{'_jnx_els_v_index'}; my $padding = '00000000000000000000000000000000' x 4; # This has bits 516 - 536 on my $portlist2 = $padding . '1FFFFF'; # This has bits 512 - 515 on my $portlist3 = $padding . 'E0'; # To simplify the expected value, we're only going to define the mapping # for five ports $test->{info}{store}{bp_index} = {513 => 505, 514 => 507, 515 => 509, 516 => 511, 536 => 551}; $test->{info}{store}{qb_v_untagged} = {2 => pack("H*", $portlist2), 3 => pack("H*", $portlist3)}; $expected = {505 => [120], 507 => [120], 509 => [120], 511 => [0], 551 => [0]}; cmp_deeply($test->{info}->i_vlan_membership_untagged(), $expected, q(VLAN membership untagged returned expected values)); $test->{info}->clear_cache(); cmp_deeply($test->{info}->i_vlan_membership_untagged(), undef, q(No data returns undef)); } # These is no longer defined in the class, but tested due to past issues with # VLAN mapping due to changes with the introduction of ELS. See issue #67 # Juniper EX4300 Missing/Wrong information #67 sub qb_fw_vlan : Tests(4) { my $test = shift; can_ok($test->{info}, 'qb_fw_vlan'); my $expected = {'393216.0.19.149.30.221.37' => 114, '458752.0.9.245.16.59.121' => 2088}; cmp_deeply($test->{info}->qb_fw_vlan(), $expected, q(ELS forwarding table entries to VLAN IDs returned expected values)); delete $test->{info}{'_jnx_els_v_index'}; $test->{info}{store}{qb_fw_port} = {'2.0.19.149.30.221.37' => 513, '3.0.9.245.16.59.121' => 507}; $expected = {'2.0.19.149.30.221.37' => 0, '3.0.9.245.16.59.121' => 120}; cmp_deeply($test->{info}->qb_fw_vlan(), $expected, q(Older forwarding table entries to VLAN IDs returned expected values)); $test->{info}->clear_cache(); cmp_deeply($test->{info}->qb_fw_vlan(), {}, q(No data returns empty hash)); } sub e_index : Tests(3) { my $test = shift; can_ok($test->{info}, 'e_index'); my $expected = { '1' => '01000000', '1.1.0.0' => '01010000', '2' => '02000000', '2.1.1.0' => '02010100', '2.1.2.0' => '02010200', '2.2.1.0' => '02020100', '2.2.2.0' => '02020200', '4' => '04000000', '4.1.1.1' => '04010101', '4.1.2.1' => '04010201', '4.2.1.1' => '04020101', '4.2.2.1' => '04020201', '7' => '07000000', '7.1.0.0' => '07010000', '7.2.0.0' => '07020000', '8' => '08000000', '8.1.1.0' => '08010100', '8.1.2.0' => '08010200', '8.1.3.0' => '08010300', '8.2.1.0' => '08020100', '8.2.2.0' => '08020200', '8.2.3.0' => '08020300', '9' => '09000000', '9.1.0.0' => '09010000', '9.2.0.0' => '09020000' }; cmp_deeply($test->{info}->e_index(), $expected, q(Entity index returned expected values)); $test->{info}->clear_cache(); cmp_deeply($test->{info}->e_index(), {}, q(No data returns empty hash)); } sub e_class : Tests(3) { my $test = shift; can_ok($test->{info}, 'e_class'); my $expected = { '1' => 'chassis', '1.1.0.0' => 'container', '2' => 'container', '2.1.1.0' => 'powerSupply', '2.1.2.0' => 'powerSupply', '2.2.1.0' => 'powerSupply', '2.2.2.0' => 'powerSupply', '4' => 'container', '4.1.1.1' => 'fan', '4.1.2.1' => 'fan', '4.2.1.1' => 'fan', '4.2.2.1' => 'fan', '7' => 'container', '7.1.0.0' => 'module', '7.2.0.0' => 'module', '8' => 'container', '8.1.1.0' => 'module', '8.1.2.0' => 'module', '8.1.3.0' => 'module', '8.2.1.0' => 'module', '8.2.2.0' => 'module', '8.2.3.0' => 'module', '9' => 'container', '9.1.0.0' => 'module', '9.2.0.0' => 'module' }; cmp_deeply($test->{info}->e_class(), $expected, q(Entity classes returned expected values)); $test->{info}->clear_cache(); cmp_deeply($test->{info}->e_class(), {}, q(No data returns empty hash)); } sub e_descr : Tests(3) { my $test = shift; can_ok($test->{info}, 'e_descr'); my $expected = { '1' => 'Juniper Virtual Chassis Ethernet Switch', '1.1.0.0' => 'chassis frame', '2' => 'Power Supply slot', '2.1.1.0' => 'Power Supply: Power Supply 0 @ 0/0/*', '2.1.2.0' => 'Power Supply: Power Supply 1 @ 0/1/*', '2.2.1.0' => 'Power Supply: Power Supply 0 @ 1/0/*', '2.2.2.0' => 'Power Supply: Power Supply 1 @ 1/1/*', '4' => 'FAN slot', '4.1.1.1' => 'FAN 0 @ 0/0/0', '4.1.2.1' => 'FAN 1 @ 0/1/0', '4.2.1.1' => 'FAN 0 @ 1/0/0', '4.2.2.1' => 'FAN 1 @ 1/1/0', '7' => 'FPC slot', '7.1.0.0' => 'FPC: EX4300-48T @ 0/*/*', '7.2.0.0' => 'FPC: EX4300-48T @ 1/*/*', '8' => 'PIC slot', '8.1.1.0' => 'PIC: 48x 10/100/1000 Base-T @ 0/0/*', '8.1.2.0' => 'PIC: 4x 40GE QSFP+ @ 0/1/*', '8.1.3.0' => 'PIC: 4x 1G/10G SFP/SFP+ @ 0/2/*', '8.2.1.0' => 'PIC: 48x 10/100/1000 Base-T @ 1/0/*', '8.2.2.0' => 'PIC: 4x 40GE QSFP+ @ 1/1/*', '8.2.3.0' => 'PIC: 4x 1G/10G SFP/SFP+ @ 1/2/*', '9' => 'Routing Engine slot', '9.1.0.0' => 'Routing Engine 0', '9.2.0.0' => 'Routing Engine 1' }; cmp_deeply($test->{info}->e_descr(), $expected, q(Entity descriptions returned expected values)); $test->{info}->clear_cache(); cmp_deeply($test->{info}->e_descr(), {}, q(No data returns empty hash)); } sub e_serial : Tests(3) { my $test = shift; can_ok($test->{info}, 'e_serial'); my $expected = { '1' => 'AB0123456789', '2.1.1.0' => '1EDD1234567', '2.1.2.0' => '1EDD2345678', '2.2.1.0' => '1EDD3456789', '2.2.2.0' => '1EDD4567890', '7.1.0.0' => 'PE1234567890', '7.2.0.0' => 'PE0123456789', '8.1.3.0' => 'MY1234567890', '8.2.3.0' => 'MY0123456789', '9.1.0.0' => 'PE2345678901', '9.2.0.0' => 'PE3456789012' }; cmp_deeply($test->{info}->e_serial(), $expected, q(Entity serial numbers returned expected values)); $test->{info}->clear_cache(); cmp_deeply($test->{info}->e_serial(), {}, q(No data returns empty hash)); } sub e_fru : Tests(3) { my $test = shift; can_ok($test->{info}, 'e_fru'); my $expected = { '1' => 'false', '1.1.0.0' => 'false', '2' => 'false', '2.1.1.0' => 'true', '2.1.2.0' => 'true', '2.2.1.0' => 'true', '2.2.2.0' => 'true', '4' => 'false', '4.1.1.1' => 'false', '4.1.2.1' => 'false', '4.2.1.1' => 'false', '4.2.2.1' => 'false', '7' => 'false', '7.1.0.0' => 'true', '7.2.0.0' => 'true', '8' => 'false', '8.1.1.0' => 'false', '8.1.2.0' => 'false', '8.1.3.0' => 'true', '8.2.1.0' => 'false', '8.2.2.0' => 'false', '8.2.3.0' => 'true', '9' => 'false', '9.1.0.0' => 'true', '9.2.0.0' => 'true' }; cmp_deeply($test->{info}->e_fru(), $expected, q(Entity FRUs returned expected values)); $test->{info}->clear_cache(); cmp_deeply($test->{info}->e_fru(), {}, q(No data returns empty hash)); } sub e_type : Tests(3) { my $test = shift; can_ok($test->{info}, 'e_type'); my $expected = { '1' => 'jnxChassisEX4300', '2' => 'jnxEX4300SlotPower', '1.1.0.0' => 'jnxChassisEX4300', '2.1.1.0' => 'jnxEX4300Power', '2.1.2.0' => 'jnxEX4300Power', '2.2.1.0' => 'jnxEX4300Power', '2.2.2.0' => 'jnxEX4300Power', '4' => 'jnxEX4300SlotFan', '4.1.1.1' => 'jnxEX4300Fan', '4.1.2.1' => 'jnxEX4300Fan', '4.2.1.1' => 'jnxEX4300Fan', '4.2.2.1' => 'jnxEX4300Fan', '7' => 'jnxEX4300SlotFPC', '7.1.0.0' => 'jnxEX4300FPC', '7.2.0.0' => 'jnxEX4300FPC', '8' => 'jnxEX4300MediaCardSpacePIC', '8.1.1.0' => 'jnxProductEX4300port48T', '8.1.2.0' => 'jnxPicEX4300QSFP4Port', '8.1.3.0' => 'jnxPicEX4300UplinkSFPPlus4Port', '8.2.1.0' => 'jnxProductEX4300port48T', '8.2.2.0' => 'jnxPicEX4300QSFP4Port', '8.2.3.0' => 'jnxPicEX4300UplinkSFPPlus4Port', '9' => 'jnxEX4300RE0', '9.1.0.0' => 'jnxEX4300RE0', '9.2.0.0' => 'jnxEX4300RE0' }; cmp_deeply($test->{info}->e_type(), $expected, q(Entity types returned expected values)); $test->{info}->clear_cache(); cmp_deeply($test->{info}->e_type(), {}, q(No data returns empty hash)); } sub e_vendor : Tests(3) { my $test = shift; can_ok($test->{info}, 'e_vendor'); my $expected = { '1' => 'juniper', '2' => 'juniper', '1.1.0.0' => 'juniper', '2.1.1.0' => 'juniper', '2.1.2.0' => 'juniper', '2.2.1.0' => 'juniper', '2.2.2.0' => 'juniper', '4' => 'juniper', '4.1.1.1' => 'juniper', '4.1.2.1' => 'juniper', '4.2.1.1' => 'juniper', '4.2.2.1' => 'juniper', '7' => 'juniper', '7.1.0.0' => 'juniper', '7.2.0.0' => 'juniper', '8' => 'juniper', '8.1.1.0' => 'juniper', '8.1.2.0' => 'juniper', '8.1.3.0' => 'juniper', '8.2.1.0' => 'juniper', '8.2.2.0' => 'juniper', '8.2.3.0' => 'juniper', '9' => 'juniper', '9.1.0.0' => 'juniper', '9.2.0.0' => 'juniper' }; cmp_deeply($test->{info}->e_vendor(), $expected, q(Entity vendor returned expected values)); $test->{info}->clear_cache(); cmp_deeply($test->{info}->e_vendor(), {}, q(No data returns empty hash)); } sub e_pos : Tests(3) { my $test = shift; can_ok($test->{info}, 'e_pos'); my $expected = { '1' => '01000000', '1.1.0.0' => '01010000', '2' => '02000000', '2.1.1.0' => '02010100', '2.1.2.0' => '02010200', '2.2.1.0' => '02020100', '2.2.2.0' => '02020200', '4' => '04000000', '4.1.1.1' => '04010101', '4.1.2.1' => '04010201', '4.2.1.1' => '04020101', '4.2.2.1' => '04020201', '7' => '07000000', '7.1.0.0' => '07010000', '7.2.0.0' => '07020000', '8' => '08000000', '8.1.1.0' => '08010100', '8.1.2.0' => '08010200', '8.1.3.0' => '08010300', '8.2.1.0' => '08020100', '8.2.2.0' => '08020200', '8.2.3.0' => '08020300', '9' => '09000000', '9.1.0.0' => '09010000', '9.2.0.0' => '09020000' }; cmp_deeply($test->{info}->e_pos(), $expected, q(Entity position returned expected values)); $test->{info}->clear_cache(); cmp_deeply($test->{info}->e_pos(), {}, q(No data returns empty hash)); } sub e_parent : Tests(3) { my $test = shift; can_ok($test->{info}, 'e_parent'); my $expected = { '1' => '00000000', '1.1.0.0' => '01000000', '2' => '01000000', '2.1.1.0' => '02000000', '2.1.2.0' => '02000000', '2.2.1.0' => '02000000', '2.2.2.0' => '02000000', '4' => '01000000', '4.1.1.1' => '04000000', '4.1.2.1' => '04000000', '4.2.1.1' => '04000000', '4.2.2.1' => '04000000', '7' => '01000000', '7.1.0.0' => '07000000', '7.2.0.0' => '07000000', '8' => '07000000', '8.1.1.0' => '08000000', '8.1.2.0' => '08000000', '8.1.3.0' => '08000000', '8.2.1.0' => '08000000', '8.2.2.0' => '08000000', '8.2.3.0' => '08000000', '9' => '01000000', '9.1.0.0' => '09000000', '9.2.0.0' => '09000000' }; cmp_deeply($test->{info}->e_parent(), $expected, q(Entity parent returned expected values)); $test->{info}->clear_cache(); cmp_deeply($test->{info}->e_parent(), {}, q(No data returns empty hash)); } 1;