示例#1
0
    def test_base_address_reassignment_qsfp(self, test_firefly):
        with \
                patch.object(I2CDevice, 'write8') as mock_I2C_write8, \
                patch.object(I2CDevice, 'readU8') as mock_I2C_readU8, \
                patch.object(I2CDevice, 'writeList') as mock_I2C_writeList, \
                patch.object(I2CDevice, 'readList') as mock_I2C_readList:
            # Set up the mocks
            mock_I2C_readList.side_effect = model_I2C_readList
            mock_I2C_writeList.side_effect = model_I2C_writeList
            mock_I2C_write8.side_effect = model_I2C_write8
            mock_I2C_readU8.side_effect = model_I2C_readU8

            mock_I2C_SwitchDeviceQSFP()  # Model a QSFP device
            mock_registers_reset()  # reset the register systems, PS is 0

            # Check that with no arguments, the base address is 0x50
            test_firefly = FireFly()
            assert (test_firefly._interface._device.address == 0x50)

            # Check that if a base address in correct range is set, it takes effect
            mock_registers_reset()  # reset the register systems, PS is 0
            test_firefly = FireFly(base_address=0x60)
            assert (test_firefly._interface._device.address == 0x60)

            # Check that if a base address out of range is set, the address stays the same
            mock_registers_reset()  # reset the register systems, PS is 0
            test_firefly = FireFly(base_address=0x90)
            assert (test_firefly._interface._device.address == 0x50)
示例#2
0
    def test_gpio_not_present(self, test_firefly):

        # Make sure this is the last test; it WILL mess with imports...

        with patch.dict('sys.modules', gpiod=None):
            # Remove gpiod module and re-run the initial include process for pac1921
            reload(odin_devices.firefly)
            from odin_devices.firefly import FireFly as FireFly_tmp

            with \
                    patch.object(I2CDevice, 'write8') as mock_I2C_write8, \
                    patch.object(I2CDevice, 'readU8') as mock_I2C_readU8, \
                    patch.object(I2CDevice, 'writeList') as mock_I2C_writeList, \
                    patch.object(I2CDevice, 'readList') as mock_I2C_readList:
                # Set up the mocks
                mock_I2C_readList.side_effect = model_I2C_readList
                mock_I2C_writeList.side_effect = model_I2C_writeList
                mock_I2C_write8.side_effect = model_I2C_write8
                mock_I2C_readU8.side_effect = model_I2C_readU8

                mock_registers_reset()  # reset the register systems, PS is 0
                mock_I2C_SwitchDeviceCXP()  # Model a CXP device

                # Check that instantiation without select line does not throw an error
                test_firefly = FireFly()

                # Check that instantiation with a select line will thrown an error
                with pytest.raises(Exception,
                                   match=".*GPIO control is not available.*"):
                    test_firefly = FireFly(select_line='test')
示例#3
0
    def test_channel_enable_readback_qsfp(self, test_firefly):
        with \
                patch.object(I2CDevice, 'write8') as mock_I2C_write8, \
                patch.object(I2CDevice, 'readU8') as mock_I2C_readU8, \
                patch.object(I2CDevice, 'writeList') as mock_I2C_writeList, \
                patch.object(I2CDevice, 'readList') as mock_I2C_readList:
            # Set up the mocks
            mock_I2C_readList.side_effect = model_I2C_readList
            mock_I2C_writeList.side_effect = model_I2C_writeList
            mock_I2C_write8.side_effect = model_I2C_write8
            mock_I2C_readU8.side_effect = model_I2C_readU8

            mock_registers_reset()  # reset the register systems, PS is 0
            mock_I2C_SwitchDeviceQSFP()  # Model a QSFP device

            # Disable all channels by default (has already been tested)
            test_firefly = FireFly()

            # Selectively enable channels 1 and 3 combined (ch1 is first channel for QSFP)
            test_firefly.enable_tx_channels(FireFly.CHANNEL_01
                                            | FireFly.CHANNEL_03)

            # Check the reported result, True is disabled
            assert (test_firefly.get_disabled_tx_channels() == [
                False, True, False, True
            ])
示例#4
0
    def test_initial_channel_disable(self, test_firefly):
        with \
                patch.object(I2CDevice, 'write8') as mock_I2C_write8, \
                patch.object(I2CDevice, 'readU8') as mock_I2C_readU8, \
                patch.object(I2CDevice, 'writeList') as mock_I2C_writeList, \
                patch.object(I2CDevice, 'readList') as mock_I2C_readList:
            # Set up the mocks
            mock_I2C_readList.side_effect = model_I2C_readList
            mock_I2C_writeList.side_effect = model_I2C_writeList
            mock_I2C_write8.side_effect = model_I2C_write8
            mock_I2C_readU8.side_effect = model_I2C_readU8

            mock_registers_reset()  # reset the register systems, PS is 0

            mock_I2C_SwitchDeviceQSFP()  # Model a QSFP device
            test_firefly = FireFly()

            # Check that the Tx channels have been left in a disabled state assuming 4 channels
            assert (test_firefly.num_channels == 4
                    )  # This test is valid for 4-channel devices
            assert (mock_registers_QSFP['lower'][86] & 0b1111 == 0b1111
                    )  # Tx Disable bits

            mock_registers_reset()  # reset the register systems, PS is 0

            mock_I2C_SwitchDeviceCXP()  # Model a CXP device
            test_firefly = FireFly()

            # Check that the Tx channels have been left in a disabled state assuming 4 channels
            assert (test_firefly.num_channels == 12
                    )  # This test is valid for 4-channel devices
            assert (mock_registers_CXP['lower'][52] & 0b1111 == 0b1111
                    )  # Tx 08-11 Disable bits
            assert (mock_registers_CXP['lower'][53] == 0b11111111
                    )  # Tx 00-07 Disable bits
示例#5
0
    def test_manual_interface_type(self, test_firefly):
        with \
                patch.object(I2CDevice, 'write8') as mock_I2C_write8, \
                patch.object(I2CDevice, 'readU8') as mock_I2C_readU8, \
                patch.object(I2CDevice, 'writeList') as mock_I2C_writeList, \
                patch.object(I2CDevice, 'readList') as mock_I2C_readList:
            # Set up the mocks
            mock_I2C_readList.side_effect = model_I2C_readList
            mock_I2C_writeList.side_effect = model_I2C_writeList
            mock_I2C_write8.side_effect = model_I2C_write8
            mock_I2C_readU8.side_effect = model_I2C_readU8

            mock_registers_reset()  # reset the register systems

            # Check that a manual interface will override an automatic one if specified
            mock_autodetect = MagicMock()
            with patch.object(FireFly, '_get_interface') as mock_autodetect:
                mock_autodetect.return_value = FireFly.INTERFACE_CXP  # Force auto to return CXP
                mock_I2C_SwitchDeviceQSFP()  # Model a QSFP device
                test_firefly = FireFly(
                    Interface_Type=FireFly.INTERFACE_QSFP)  # Force QSFP
                assert (isinstance(test_firefly._interface, _interface_QSFP))
                assert (not isinstance(test_firefly._interface,
                                       _interface_CXP))

            # Check that an invalid manually specified interface type will raise an error
            with pytest.raises(
                    Exception,
                    match=".*Manually specified interface type was invalid.*"):
                test_firefly = FireFly(Interface_Type='foo')
示例#6
0
    def test_channel_enable_cxp(self, test_firefly):
        with \
                patch.object(I2CDevice, 'write8') as mock_I2C_write8, \
                patch.object(I2CDevice, 'readU8') as mock_I2C_readU8, \
                patch.object(I2CDevice, 'writeList') as mock_I2C_writeList, \
                patch.object(I2CDevice, 'readList') as mock_I2C_readList:
            # Set up the mocks
            mock_I2C_readList.side_effect = model_I2C_readList
            mock_I2C_writeList.side_effect = model_I2C_writeList
            mock_I2C_write8.side_effect = model_I2C_write8
            mock_I2C_readU8.side_effect = model_I2C_readU8

            mock_registers_reset()  # reset the register systems, PS is 0
            mock_I2C_SwitchDeviceCXP()  # Model a CXP device

            # Disable all channels by default (has already been tested)
            test_firefly = FireFly()

            # Selectively enable channel 1(ch1 is second channel for QSFP)
            test_firefly.enable_tx_channels(FireFly.CHANNEL_01)
            assert (test_firefly.num_channels == 12
                    )  # This test is valid for 12-channel devices
            assert (mock_registers_CXP['lower'][52] & 0b1111 == 0b1111)
            assert (mock_registers_CXP['lower'][53] == 0b11111101)

            # Selectively enable channels 1 and 3 combined (ch1 is first channel for QSFP)
            test_firefly.enable_tx_channels(FireFly.CHANNEL_01
                                            | FireFly.CHANNEL_09)
            assert (mock_registers_CXP['lower'][52] & 0b1111 == 0b1101)
            assert (mock_registers_CXP['lower'][53] == 0b11111101)

            # Check setting valid channels at limits does not cause an error
            test_firefly.enable_tx_channels(FireFly.CHANNEL_00)
            test_firefly.enable_tx_channels(FireFly.CHANNEL_11)
示例#7
0
    def tests_channel_enable_readback_field_qsfp(self, test_firefly):
        # This function essentially does the same thing as above, but presents the
        # result differently.
        with \
                patch.object(I2CDevice, 'write8') as mock_I2C_write8, \
                patch.object(I2CDevice, 'readU8') as mock_I2C_readU8, \
                patch.object(I2CDevice, 'writeList') as mock_I2C_writeList, \
                patch.object(I2CDevice, 'readList') as mock_I2C_readList:
            # Set up the mocks
            mock_I2C_readList.side_effect = model_I2C_readList
            mock_I2C_writeList.side_effect = model_I2C_writeList
            mock_I2C_write8.side_effect = model_I2C_write8
            mock_I2C_readU8.side_effect = model_I2C_readU8

            mock_registers_reset()  # reset the register systems, PS is 0
            mock_I2C_SwitchDeviceQSFP(
            )  # Model a QSFP device (4 channel, offset 1)

            # Disable all channels by default (has already been tested)
            test_firefly = FireFly()

            # Selectively enable channels 1 and 3 combined (ch1 is first channel for QSFP)
            test_firefly.enable_tx_channels(FireFly.CHANNEL_ALL)
            test_firefly.disable_tx_channels(FireFly.CHANNEL_01
                                             | FireFly.CHANNEL_03)

            # Check the reported result, True is disabled
            assert (test_firefly.get_disabled_tx_channels_field() == (
                FireFly.CHANNEL_01 | FireFly.CHANNEL_03))
示例#8
0
    def test_tx_temp_reporting_qsfp(self, test_firefly):
        with \
                patch.object(I2CDevice, 'write8') as mock_I2C_write8, \
                patch.object(I2CDevice, 'readU8') as mock_I2C_readU8, \
                patch.object(I2CDevice, 'writeList') as mock_I2C_writeList, \
                patch.object(I2CDevice, 'readList') as mock_I2C_readList:
            # Set up the mocks
            mock_I2C_readList.side_effect = model_I2C_readList
            mock_I2C_writeList.side_effect = model_I2C_writeList
            mock_I2C_write8.side_effect = model_I2C_write8
            mock_I2C_readU8.side_effect = model_I2C_readU8

            mock_registers_reset()  # reset the register systems, PS is 0
            mock_I2C_SwitchDeviceQSFP()  # Model a QSFP device

            # Store temperature 40C in CXP device Tx/Rx and read result
            mock_registers_QSFP['lower'][
                22] = 0b00101000  # 2's compliment 8-bit
            test_firefly = FireFly()
            assert (test_firefly.get_temperature(
                direction=FireFly.DIRECTION_TX) == 40.0)

            # Check that the 2's comliment works by reading a negative back
            mock_registers_QSFP['lower'][
                22] = 0b10000000  # 2's compliment 8-bit
            test_firefly = FireFly()
            assert (test_firefly.get_temperature(
                direction=FireFly.DIRECTION_TX) == -128.0)
示例#9
0
    def test_page_switching_qsfp(self, test_firefly):
        # Check that selecting a field accessible on page 1 results in the page being changed
        # Since the mocking already simulates pages, this can be checked by placing data on the
        # virtual upper page 01 only to see if it is received correctly.

        with \
                patch.object(I2CDevice, 'write8') as mock_I2C_write8, \
                patch.object(I2CDevice, 'readU8') as mock_I2C_readU8, \
                patch.object(I2CDevice, 'writeList') as mock_I2C_writeList, \
                patch.object(I2CDevice, 'readList') as mock_I2C_readList:
            # Set up the mocks
            mock_I2C_readList.side_effect = model_I2C_readList
            mock_I2C_writeList.side_effect = model_I2C_writeList
            mock_I2C_write8.side_effect = model_I2C_write8
            mock_I2C_readU8.side_effect = model_I2C_readU8

            mock_registers_reset()  # reset the register systems, PS is 0

            mock_I2C_SwitchDeviceQSFP()  # Model a QSFP device
            test_firefly = FireFly()

            # Write to the I2C Address field, which is on upper page 2 using current interface
            test_firefly._interface.write_field(
                test_firefly._interface.FLD_I2C_Address, [0xAA])

            assert (mock_registers_QSFP['lower'][127] == 2
                    )  # Check PS is now 2

            mock_registers_reset()  # reset the register systems, PS is 0

            mock_I2C_SwitchDeviceCXP()  # Model a CXP device
            test_firefly = FireFly()

            # Write to the I2C Address field, which is on upper page 2 using current interface
            test_firefly._interface.write_field(
                test_firefly._interface.FLD_I2C_Address, [0xAA])

            assert (mock_registers_CXP['lower'][127] == 2)  # Check PS is now 2
示例#10
0
    def test_base_address_reassignment_cxp(self, test_firefly):
        with \
                patch.object(I2CDevice, 'write8') as mock_I2C_write8, \
                patch.object(I2CDevice, 'readU8') as mock_I2C_readU8, \
                patch.object(I2CDevice, 'writeList') as mock_I2C_writeList, \
                patch.object(I2CDevice, 'readList') as mock_I2C_readList:
            # Set up the mocks
            mock_I2C_readList.side_effect = model_I2C_readList
            mock_I2C_writeList.side_effect = model_I2C_writeList
            mock_I2C_write8.side_effect = model_I2C_write8
            mock_I2C_readU8.side_effect = model_I2C_readU8

            mock_I2C_SwitchDeviceCXP()  # Model a CXP device
            mock_registers_reset()  # reset the register systems, PS is 0

            # CXP separates Tx and Rx activity.

            # Check that with no arguments, the base address is 0x50
            test_firefly = FireFly()
            assert (test_firefly._interface._tx_device.address == 0x50)

            # Check that if a base address in range 0x01-0x3F, either the address set or 0x50 is used
            mock_registers_reset()  # reset the register systems, PS is 0
            test_firefly = FireFly(base_address=0x30)
            assert (test_firefly._interface._tx_device.address == 0x50
                    or test_firefly._interface._tx_device.address == 0x30)

            # Check that if a base address in range 0x40-0x7E, address set is used
            mock_registers_reset()  # reset the register systems, PS is 0
            test_firefly = FireFly(base_address=0x60)
            assert (test_firefly._interface._tx_device.address == 0x60)

            # Check that the Rx address is 4 above (when 7-bit) the Tx one
            mock_registers_reset()  # reset the register systems, PS is 0
            test_firefly = FireFly()
            assert (test_firefly._interface._rx_device.address ==
                    test_firefly._interface._tx_device.address + 4)
示例#11
0
    def test_pin_control(self, test_firefly):
        temp_pin = MagicMock(spec=gpiod.Line)
        temp_pin.set_value = Mock()
        temp_pin.is_requested = Mock()
        temp_pin.is_requested.return_value = True
        with \
                patch.object(I2CDevice, 'write8') as mock_I2C_write8, \
                patch.object(I2CDevice, 'readU8') as mock_I2C_readU8, \
                patch.object(I2CDevice, 'writeList') as mock_I2C_writeList, \
                patch.object(I2CDevice, 'readList') as mock_I2C_readList:
            # Set up the mocks
            mock_I2C_readList.side_effect = model_I2C_readList
            mock_I2C_writeList.side_effect = model_I2C_writeList
            mock_I2C_write8.side_effect = model_I2C_write8
            mock_I2C_readU8.side_effect = model_I2C_readU8

            mock_registers_reset()  # reset the register systems, PS is 0
            mock_I2C_SwitchDeviceCXP()  # Model a CXP device

            # Check that if a pin is supplied it is actuated on I2C usage
            test_firefly = FireFly(select_line=temp_pin)
            temp_pin.reset_mock()
            test_firefly.get_temperature(FireFly.DIRECTION_TX)
            temp_pin.set_value.assert_any_call(0)  # Was called with 0
            temp_pin.set_value.assert_called_with(1)  # Last call was 1

            # Check that polarity is correct (selectL)
            test_firefly._interface._select_device(
            )  # Get in selected state initially
            temp_pin.reset_mock()
            test_firefly._interface._deselect_device()
            temp_pin.set_value.assert_called_with(1)  # Check deselect is high
            temp_pin.reset_mock()
            test_firefly._interface._select_device()
            temp_pin.set_value.assert_called_with(0)  # Check select is low

            # Check that if a pin is not requested already when passed in, an error is thrown
            temp_pin.is_requested.return_value = False
            with pytest.raises(Exception,
                               match=".*GPIO Line.*not requested.*user.*"):
                test_firefly = FireFly(select_line=temp_pin)

            # Check if pin is not a gpiod pin (direct or from gpio_bus) an error is raised
            with pytest.raises(Exception,
                               match=".*line was not a valid object.*"):
                test_firefly = FireFly(select_line='notaline')
示例#12
0
    def test_channel_enable_qsfp(self, test_firefly):
        with \
                patch.object(I2CDevice, 'write8') as mock_I2C_write8, \
                patch.object(I2CDevice, 'readU8') as mock_I2C_readU8, \
                patch.object(I2CDevice, 'writeList') as mock_I2C_writeList, \
                patch.object(I2CDevice, 'readList') as mock_I2C_readList:
            # Set up the mocks
            mock_I2C_readList.side_effect = model_I2C_readList
            mock_I2C_writeList.side_effect = model_I2C_writeList
            mock_I2C_write8.side_effect = model_I2C_write8
            mock_I2C_readU8.side_effect = model_I2C_readU8

            mock_registers_reset()  # reset the register systems, PS is 0
            mock_I2C_SwitchDeviceQSFP()  # Model a QSFP device

            # Disable all channels by default (has already been tested)
            test_firefly = FireFly()

            # Selectively enable channel 1(ch1 is first channel for QSFP)
            test_firefly.enable_tx_channels(FireFly.CHANNEL_01)
            assert (test_firefly.num_channels == 4
                    )  # This test is valid for 4-channel devices
            assert (mock_registers_QSFP['lower'][86] & 0b1111 == 0b1110
                    )  # Tx Disable bits

            # Selectively enable channels 1 and 3 combined (ch1 is first channel for QSFP)
            test_firefly.enable_tx_channels(FireFly.CHANNEL_01
                                            | FireFly.CHANNEL_03)
            assert (test_firefly.num_channels == 4
                    )  # This test is valid for 4-channel devices
            assert (mock_registers_QSFP['lower'][86] & 0b1111 == 0b1010
                    )  # Tx Disable bits

            # Check setting an invalid channel triggers an error
            with pytest.raises(Exception):
                test_firefly.enable_tx_channels(FireFly.CHANNEL_00)
            with pytest.raises(Exception):
                test_firefly.enable_tx_channels(FireFly.CHANNEL_05)

            # Check setting valid channels at limits does not cause an error
            test_firefly.enable_tx_channels(FireFly.CHANNEL_01)
            test_firefly.enable_tx_channels(FireFly.CHANNEL_04)
示例#13
0
    def test_device_info_report_pn(self, test_firefly):
        with \
                patch.object(I2CDevice, 'write8') as mock_I2C_write8, \
                patch.object(I2CDevice, 'readU8') as mock_I2C_readU8, \
                patch.object(I2CDevice, 'writeList') as mock_I2C_writeList, \
                patch.object(I2CDevice, 'readList') as mock_I2C_readList:
            # Set up the mocks
            mock_I2C_readList.side_effect = model_I2C_readList
            mock_I2C_writeList.side_effect = model_I2C_writeList
            mock_I2C_write8.side_effect = model_I2C_write8
            mock_I2C_readU8.side_effect = model_I2C_readU8

            mock_registers_reset()  # reset the register systems, PS is 0
            mock_I2C_SwitchDeviceQSFP()  # Model a QSFP device

            valid_part_number = 'B0425xxx0x1xxx  '
            input_vendor_name = 'PRETEND MANUFAC '

            I2CDevice.writeList(168,
                                [ord(x)
                                 for x in valid_part_number])  # Insert info
            I2CDevice.writeList(148,
                                [ord(x)
                                 for x in input_vendor_name])  # Insert info

            test_firefly = FireFly()

            # Check fields returned
            ret_pn, ret_vn, ret_oui = test_firefly.get_device_info()
            assert (valid_part_number == ret_pn)
            assert (input_vendor_name == ret_vn)
            # (OUI is already set to Samtec's one, or init will fail)

            # Check part number parts
            assert (test_firefly.data_rate_Gbps == 25)
            assert (test_firefly.num_channels == 4)

            # Check that an unsupported num of channels raises an error
            pn_unsupported_channels = 'B0625xxx0x1xxx  '  # 6-channel (not real)
            I2CDevice.writeList(
                168, [ord(x) for x in pn_unsupported_channels])  # Insert info
            with pytest.raises(Exception,
                               match=".*Unsupported number of channels: 06.*"):
                test_firefly = FireFly()

            # Check that an invalid direction raises an error
            pn_invalid_direction = 'P0425xxx0x1xxx  '  # 'P' direction (not real)
            I2CDevice.writeList(168,
                                [ord(x)
                                 for x in pn_invalid_direction])  # Insert info
            with pytest.raises(
                    Exception,
                    match=
                    ".*Data direction P in part number field not recognised.*"
            ):
                test_firefly = FireFly()

            # Check that invalid static padding fields raise an error (these never change)
            pn_invalid_static_bits = 'B0425xxx1x0xxx  '  # Static bits 0, 1 swapped
            I2CDevice.writeList(
                168, [ord(x) for x in pn_invalid_static_bits])  # Insert info
            with pytest.raises(Exception, match=".*Invalid PN static field.*"):
                test_firefly = FireFly()
示例#14
0
    def test_tx_temp_reporting_cxp(self, test_firefly):
        with \
                patch.object(I2CDevice, 'write8') as mock_I2C_write8, \
                patch.object(I2CDevice, 'readU8') as mock_I2C_readU8, \
                patch.object(I2CDevice, 'writeList') as mock_I2C_writeList, \
                patch.object(I2CDevice, 'readList') as mock_I2C_readList:
            # Set up the mocks
            mock_I2C_readList.side_effect = model_I2C_readList
            mock_I2C_writeList.side_effect = model_I2C_writeList
            mock_I2C_write8.side_effect = model_I2C_write8
            mock_I2C_readU8.side_effect = model_I2C_readU8

            mock_registers_reset()  # reset the register systems, PS is 0
            mock_I2C_SwitchDeviceCXP()  # Model a CXP device

            # Store temperature 40C in CXP device Tx and read result
            mock_registers_CXP['lower'][
                22] = 0b00101000  # 2's compliment 8-bit
            test_firefly = FireFly()
            assert (test_firefly.get_temperature(
                direction=FireFly.DIRECTION_TX) == 40.0)

            # Store temperature 40C in CXP device Rx (same register, different I2C address)
            mock_registers_CXP['lower'][
                22] = 0b00101000  # 2's compliment 8-bit
            test_firefly = FireFly()
            assert (test_firefly.get_temperature(
                direction=FireFly.DIRECTION_TX) == 40.0)

            # Check that the 2's comliment works by reading a negative back
            mock_registers_CXP['lower'][
                22] = 0b10000000  # 2's compliment 8-bit
            test_firefly = FireFly()
            assert (test_firefly.get_temperature(
                direction=FireFly.DIRECTION_TX) == -128.0)

            # Check that a duplex device supplied with no direction raises an error
            mock_registers_reset()  # reset the register systems, PS is 0
            test_firefly = FireFly()
            assert (test_firefly.direction == FireFly.DIRECTION_DUPLEX
                    )  # Test valid for duplex
            with pytest.raises(
                    I2CException,
                    match=".*Invalid direction.*could not be derived.*"):
                test_firefly.get_temperature()

            # Check that a simplex device can infer direction
            mock_registers_reset()  # reset the register systems, PS is 0
            mock_registers_CXP['upper'][0][171] = ord(
                'R')  # Force PN to reflect Rx only device
            test_firefly = FireFly()
            assert (test_firefly.direction == FireFly.DIRECTION_RX
                    )  # Test valid for Rx only
            mock_read_field = MagicMock()
            with patch.object(_interface_CXP, 'read_field') as mock_read_field:
                mock_read_field.return_value = [30]
                test_firefly.get_temperature()
                print(mock_read_field.mock_calls)

                # Assert that the Rx version was read
                mock_read_field.assert_called_with(
                    _interface_CXP.FLD_Rx_Temperature)

                # Assert that the Tx version was not read
                assert (call(_interface_CXP.FLD_Rx_Temperature)
                        in mock_read_field.mock_calls)
                assert (call(_interface_CXP.FLD_Tx_Temperature)
                        not in mock_read_field.mock_calls)
示例#15
0
    def test_interface_detect(self, test_firefly):
        """
        Check the interface detection process, which will be performed to determine
        if the device is QSFP+ or CXP. To perform this test, the select line needs to be used.
        """

        # Create relevant mocks
        writemock = MagicMock()
        readmock = MagicMock()
        temp_pin = MagicMock(spec=gpiod.Line)
        temp_pin.set_value = Mock()
        temp_pin.is_requested = Mock()
        temp_pin.is_requested.return_value = True
        with \
                patch.object(I2CDevice, 'write8') as writemock, \
                patch.object(I2CDevice, 'readList') as readmock:

            # Check that the correct OUI address is read, using the correct write-read pattern
            writemock.reset_mock()
            readmock.reset_mock()
            FireFly._get_interface(select_line=temp_pin, default_address=0x50)
            writemock.assert_called_with(
                127, 0)  # Writes page 0 to page select byte
            readmock.assert_any_call(165, 3)  # Reads OUI bytes for QSFP+
            readmock.assert_any_call(168, 3)  # Reads OUI bytes for CXP

            # Check that reading the OUI for a QSFP+ device will result in identification
            readmock.side_effect = lambda reg, ln: {  # Set fake register to return expected count
                165: [0x04, 0xC8, 0x80],  # QSFP+ OUI is Samtek
                168: [0, 0, 0]
            }[reg]  # QSFP first 3 digits of PN)
            assert (FireFly._get_interface(
                select_line=temp_pin,
                default_address=0x50) == FireFly.INTERFACE_QSFP)

            # Check that reading the OUI for a CXP device will result in identification
            readmock.side_effect = lambda reg, ln: {  # Set fake register to return expected count
                165: [0, 0, 0],  # CXP end of vendor name in ASCII
                168: [0x04, 0xC8, 0x80]
            }[reg]  # CXP OUI is Samtek
            assert (FireFly._get_interface(
                select_line=temp_pin,
                default_address=0x50) == FireFly.INTERFACE_CXP)

        # Check that the mocking model for different types also works
        print("Testing the mocked registers:")
        with \
                patch.object(I2CDevice, 'write8') as mock_I2C_write8, \
                patch.object(I2CDevice, 'readU8') as mock_I2C_readU8, \
                patch.object(I2CDevice, 'writeList') as mock_I2C_writeList, \
                patch.object(I2CDevice, 'readList') as mock_I2C_readList:
            # Set up the mocks
            mock_I2C_readList.side_effect = model_I2C_readList
            mock_I2C_writeList.side_effect = model_I2C_writeList
            mock_I2C_write8.side_effect = model_I2C_write8
            mock_I2C_readU8.side_effect = model_I2C_readU8

            mock_registers_reset()  # reset the register systems

            mock_I2C_SwitchDeviceCXP()  # Model a CXP device
            assert (FireFly._get_interface(
                select_line=temp_pin,
                default_address=0x50) == FireFly.INTERFACE_CXP)

            mock_I2C_SwitchDeviceQSFP()  # Model a QSFP device
            assert (FireFly._get_interface(
                select_line=temp_pin,
                default_address=0x50) == FireFly.INTERFACE_QSFP)

            # Check that an invalid value for both, raise an error
            global mock_registers_QSFP
            mock_registers_QSFP = {
                'lower': {},
                'upper': {
                    0: {},
                    1: {},
                    2: {},
                    3: {}
                }
            }  # Clear all registers
            with pytest.raises(
                    Exception,
                    match=
                    ".*Was unable to determine interface type automatically.*"
            ):
                test_firefly = FireFly()
            mock_registers_reset()  # reset the register systems (just in case)