def set_lan_configuration_parameter(self, channel, parameter, data): """Set the LAN Configuration Parameter specified: `channel` `parameterr` `data` Example: | Set Lan Configuraion Parameter | 1 | IP Address | 10 10 10 10 | | # read value first | ${oldValue}= | Get Lan Configuration Parameter | 1 | IP Address | | Set Lan Configuraion Parameter | 1 | IP Address | ${oldValue} | """ channel = int_any_base(channel) parameter = find_lan_configuration_parameter(parameter) if isinstance(data, basestring): data = [int_any_base(d) for d in data.split(' ')] data = array.array('c', [chr(c) for c in data]) req = self.create_message_request('SetLanConfigurationParameters') req.command.channel_number = channel req.parameter_selector = parameter req.data = data rsp = self.send_ipmi_message(req)
def send_raw_command(self, *bytes): """Sends a raw IPMI command. `bytes` can either be a list or serveral scalar values. If a LUN other then zero is needed, it can be given with the first value of the list by prepending 'lun=', eg. lun=3. Example: | ${values}= | Create List | 0x06 | 0x01 | | | Send Raw Command | ${values} | | | | # BMC info command | Send Raw Command | 0x06 | 0x01 | | | # same as above | Send Raw Command | lun=3 | 0x3e | 0x62 | ... | # LUN other than zero """ if isinstance(bytes[0], list): bytes = bytes[0] lun = 0 if len(bytes) > 0 and bytes[0].startswith('lun='): lun = int_any_base(bytes[0][4:]) bytes = bytes[1:] if len(bytes) < 2: raise RuntimeError('netfn and/or cmdid missing') bytes = [ int_any_base(b) for b in bytes ] raw = ''.join([chr(b) for b in bytes[1:]]) rsp = self._ipmi.raw_command(lun, bytes[0], raw) return [ord(b) for b in rsp]
def open_ipmi_lan_connection(self, host, target_address, user='', password='', routing_information=None, port=623, interface_type='ipmitool', alias=None): """Opens a LAN connection to an IPMI shelf manager. `host` is the IP or hostname of the shelf manager. `target_address` the IPMI address to which the command should be sent. `user` and `password` are used to authenticate against the shelf manager. """ host = str(host) target_address = int_any_base(target_address) user = str(user) password = str(password) port = int_any_base(port) interface = pyipmi.interfaces.create_interface(interface_type) ipmi = pyipmi.create_connection(interface) ipmi.session.set_session_type_rmcp(host, port) ipmi.session.set_auth_type_user(user, password) self._info('Opening IPMI connection to %s:%d/%02Xh' % (host, port, target_address)) ipmi.session.establish() target = pyipmi.Target(target_address, routing_information) ipmi.target = target connection = IpmiConnection(ipmi, target) self._active_connection = connection return self._cache.register(connection, alias)
def selected_sel_records_event_data_should_be_equal(self, expected_value, mask=0xffffff, msg=None): """Fails if the event data of the selected SEL record does not match the given value. Example: | Select SEL Record By Sensor Type | 0xcf | | Selected SEL Records Event Data Should Be Equal | 0xa10101 | | Selected SEL Records Event Data Should Be Equal | 0x010000 | 0x0f0000 | """ expected_value = int_any_base(expected_value) mask = int_any_base(mask) record = self._selected_sel_record # apply mask expected_value = expected_value & mask actual_value = (ord(record.event_data[0]) << 16 | ord(record.event_data[1]) << 8 | ord(record.event_data[2])) actual_value = actual_value & mask expected_value = '0x%x' % expected_value actual_value = '0x%x' % actual_value asserts.assert_equal(expected_value, actual_value, msg)
def send_raw_command(self, *bytes): """Sends a raw IPMI command. `bytes` can either be a list or serveral scalar values. If a LUN other then zero is needed, it can be given with the first value of the list by prepending 'lun=', eg. lun=3. Example: | ${values}= | Create List | 0x06 | 0x01 | | | Send Raw Command | ${values} | | | | # BMC info command | Send Raw Command | 0x06 | 0x01 | | | # same as above | Send Raw Command | lun=3 | 0x3e | 0x62 | ... | # LUN other than zero """ if isinstance(bytes[0], list): bytes = bytes[0] lun = 0 if len(bytes) > 0 and bytes[0].startswith('lun='): lun = int_any_base(bytes[0][4:]) bytes = bytes[1:] if len(bytes) < 2: raise RuntimeError('netfn and/or cmdid missing') bytes = [int_any_base(b) for b in bytes] raw = ''.join([chr(b) for b in bytes[1:]]) rsp = self._ipmi.raw_command(lun, bytes[0], raw) return [ord(b) for b in rsp]
def i2c_master_write(self, address, *data): """Perform an I2C master write access. Writes the given `data` to a slave device with address given in the `address` argument. The `data` argument can either be list of bytes, a whitespace separated list of bytes or a single byte. See the examples below. Both the `address` and `data` can be given either as strings or integers. Strings are parsed accoding to their prefix. Eg. `0x` denotes a hexadecimal number. Examples: | I2C Master Write | 0xa4 | 0x10 | | I2C Master Write | 0xa4 | 0x10 0x12 0x13 | | I2C Master Write | 0xa4 | 0x10 | 0x12 | 0x13 | """ address = int_any_base(address) if len(data) == 1: data = list_any_input(data[0]) else: data = [int_any_base(c) for c in data] logger.info('Writing %d bytes to %02xh: %s' % (len(data), address, ' '.join('%02x' % d for d in data))) data = ''.join('%c' % chr(c) for c in data) self._device.i2c_master_write(address, data)
def open_ipmi_lan_connection(self, host, target_address, user='', password='', routing_information=None, port=623, interface_type='ipmitool', alias=None): """Opens a LAN connection to an IPMI shelf manager. `host` is the IP or hostname of the shelf manager. `target_address` the IPMI address to which the command should be sent. `user` and `password` are used to authenticate against the shelf manager. """ host = str(host) target_address = int_any_base(target_address) user = str(user) password = str(password) port = int_any_base(port) interface = pyipmi.interfaces.create_interface(interface_type, 'lanplus') ipmi = pyipmi.create_connection(interface) ipmi.session.set_session_type_rmcp(host, port) ipmi.session.set_auth_type_user(user, password) self._info('Opening IPMI connection to %s:%d/%02Xh' % (host, port, target_address)) ipmi.session.establish() target = pyipmi.Target(target_address, routing_information) ipmi.target = target connection = IpmiConnection(ipmi, target) self._active_connection = connection return self._cache.register(connection, alias)
def i2c_master_write_read(self, address, length, *data): """Perform an I2C master write read access. First write the given `data` to a slave device, then read `length` bytes from it. For more information see the `I2C Master Read` and `I2C Master Write` keywords. Examples: | I2C Master Write Read | 0xa4 | 1 | 0x10 | | I2C Master Write Read | 0xa4 | 1 | 0x10 0x12 0x13 | | I2C Master Write Read | 0xa4 | 1 | 0x10 | 0x12 | 0x13 | """ address = int_any_base(address) length = int_any_base(length) if len(data) == 1: data = list_any_input(data[0]) else: data = [int_any_base(c) for c in data] logger.info('Writing %d bytes to %02xh: %s' % (len(data), address, ' '.join('%02x' % d for d in data))) data = ''.join('%c' % chr(c) for c in data) data = self._device.i2c_master_write_read(address, data, length) data = array.array('B', data) logger.info('Read %d bytes from %02xh: %s' % (length, address, ' '.join('%02x' % d for d in data))) return data
def selected_sel_records_event_data_should_be_equal(self, expected_value, mask=0xffffff, msg=None): """Fails if the event data of the selected SEL record does not match the given value. Example: | Select SEL Record By Sensor Type | 0xcf | | Selected SEL Records Event Data Should Be Equal | 0xa10101 | | Selected SEL Records Event Data Should Be Equal | 0x010000 | 0x0f0000 | """ expected_value = int_any_base(expected_value) mask = int_any_base(mask) record = self._selected_sel_record # apply mask expected_value = expected_value & mask actual_value = (record.event_data[0] << 16 | record.event_data[1] << 8 | record.event_data[2]) actual_value = actual_value & mask expected_value = '0x%x' % expected_value actual_value = '0x%x' % actual_value asserts.assert_equal(expected_value, actual_value, msg)
def selected_sdr_sensor_state_should_be_equal(self, expected_state, mask=0x7fff, msg=None): """Fails unless the state of the selected senor matches the given one. """ expected_state = int_any_base(expected_state) mask = int_any_base(mask) self.sensor_state_should_be_equal(self._selected_sdr.device_id_string, expected_state, self._selected_sdr, mask, msg)
def read_fru_data(self, offset, count, fru_id=0): """Reads data bytes from FRU data area. `offset` `count` `fru_id` """ fru_id = int(fru_id) offset = int_any_base(offset) count = int_any_base(count) data_string = self._ipmi.read_fru_data(offset, count, fru_id) data = [ord(c) for c in data_string] return data
def i2c_master_read(self, address, length=1): """Perform an I2C master read access. Read `length` bytes from a slave device with the address given in the `address` argument. """ address = int_any_base(address) length = int_any_base(length) data = self._device.i2c_master_read(address, length) data = array.array('B', data) logger.info('Read %d bytes from %02xh: %s', length, address, ' '.join('%02x' % d for d in data)) return data
def get_power_level(self, fruid, power_type, offset): """return the specified power level for the fru `fruid` `power_type` `offset` """ fruid = int_any_base(fruid) power_type = int_any_base(power_type) offset = int_any_base(offset) pwr = self._ipmi.get_power_level(fruid, power_type) return pwr.power_levels[offset]
def hpm_finish_firmware_upload(self, component_name, size, expected_cc=pyipmi.msgs.constants.CC_OK): size = int_any_base(size) id = self._ipmi.find_component_id_by_descriptor(component_name) expected_cc = int_any_base(expected_cc) if id is None: raise AssertionError('component_name=%s not found' % (component_name)) try: self._ipmi.finish_firmware_upload(id, size) except CompletionCodeError, e: if e.cc == expected_cc: pass else: raise CompletionCodeError(e.cc)
def select_sel_record_by_record_id(self, record_id): record_id = int_any_base(record_id) for record in self._sel_records: if record.record_id == record_id: self._selected_sel_record = record return
def partial_add_sdr(self, reservation_id, record_id, offset, progress, data): record_id = int_any_base(record_id) offset = int_any_base(offset) progress = int_any_base(progress) if isinstance(data, basestring): data = [int_any_base(d) for d in data.split(' ')] elif isinstance(data, list): data = data else: data = [int_any_base(data)] data = array.array('c', [chr(c) for c in data]) return self._ipmi.partial_add_sdr( reservation_id, record_id, offset, progress, data)
def selected_sdr_entity_instance_should_be(self, expected_entity_instance, msg=None): expected_entity_instance = int_any_base(expected_entity_instance) actual_entity_instance = self._selected_sdr.entity_instance asserts.assert_equal(expected_entity_instance, actual_entity_instance, msg)
def get_hotswap_sdr(self, entity): """Get the entities hotswap sensor SDR Entity can be specified by 'entitiy_id:entity_instance' Valid entitiy_id: Power Module= 0x0a Cooling Unit = 0x1e Picmg Front Board= 0xa0 Picmg Rear Transition Module= 0xc0 Picmg Advanced MC = 0xc1 Picmg Microtca Carrier Hub = 0xc2 Picmg Shelf Management Controller = 0xf0 Picmg FIlteration Unit = 0xf1 Picmg Shelf FRU Information = 0xf2 """ (entity_id, entity_instance) = entity.split(':') entity_id = find_entity_type_id(entity_id) entity_instance = int_any_base(entity_instance) for sdr in self._sdr_entries(): if (sdr.type is not pyipmi.sdr.SDR_TYPE_FULL_SENSOR_RECORD and \ sdr.type is not pyipmi.sdr.SDR_TYPE_COMPACT_SENSOR_RECORD): continue if sdr.sensor_type_code != \ pyipmi.sensor.SENSOR_TYPE_FRU_HOT_SWAP: continue if sdr.entity_id == entity_id and \ sdr.entity_instance == entity_instance: return sdr raise AssertionError('Hotswap Sensor for entity %s %s not found' \ % (entity_id, entity_instance))
def spi_transfer(self, *data): """Performs a SPI access. Writes a stream of bytes (given in `data`) on the SPI interface while reading back the same amount of bytes. The read back has the same length as the input data. If you want to read more data than writing on the bus you have to send dummy bytes. Examples: | SPI Write | 0x10 | | SPI Write | 0x10 0x12 0x13 | | SPI Write | 0x10 | 0x12 | 0x13 | | ${ret}= | SPI Write | 0x10 | 0x12 | 0x13 | # ${ret} is an array of 3 bytes | """ if len(data) == 1: data = list_any_input(data[0]) else: data = [int_any_base(c) for c in data] logger.info('Writing %d bytes: %s' % (len(data), ' '.join('%02x' % d for d in data))) data = ''.join('%c' % chr(c) for c in data) data = self._device.spi_write(data) data = array.array('B', data) logger.info('Read %d bytes: %s' % (len(data), ' '.join('%02x' % d for d in data))) return data
def product_id_should_be(self, product_id): """Fails if the GetDeviceID command response does not contain the given `device_id`. """ product_id = int_any_base(product_id) device_id = self._ipmi.get_device_id() asserts.assert_equal(device_id.product_id, product_id)
def manufacturer_id_should_be(self, manufacturer_id): """Fails if the GetDeviceID command response does not contain the given `manufacturer_id`. """ manufacturer_id = int_any_base(manufacturer_id) device_id = self._ipmi.get_device_id() asserts.assert_equal(device_id.manufacturer_id, manufacturer_id)
def fru_data_at_offset_should_be(self, offset, expected_data, fru_id=0, msg=None): """Fails unless the FRU data contains the expected data at the given offset.""" fru_id = int(fru_id) offset = int_any_base(offset) expected_data = [int_any_base(d) for d in expected_data.split(' ')] data = self._fru_data(fru_id)[offset:offset+len(expected_data)] # convert to common data structure data = array.array('B', data) expected_data = array.array('B', expected_data) asserts.assert_equal(expected_data, data, msg)
def send_ipmi_message(self, message, expected_cc=0x00): expected_cc = int_any_base(expected_cc) rsp = self._ipmi.send_message(message) cc = rsp.completion_code msg = 'Command returned with return completion code 0x%02x, ' \ 'but should be 0x%02x' % (cc, expected_cc) asserts.assert_equal(expected_cc, cc, msg, values=False) return rsp
def sensor_state_should_be_equal(self, name, expected_state, sdr=None, mask=0x7fff, msg=None): """Fails unless the sensor state of the sensor with name `name` matches the given one. """ expected_state = int_any_base(expected_state) mask = int_any_base(mask) if sdr is None: sdr = self._find_sdr_by_name(name) (_, actual_state) = self._ipmi.get_sensor_reading(sdr.number) # apply mask expected_state = expected_state & mask actual_state = actual_state & mask asserts.assert_equal(expected_state, actual_state, msg)
def write_fru_data(self, offset, data, fru_id=0): """Writes data bytes to FRU data area. `offset` `data` `fru_id` """ fru_id = int(fru_id) offset = int_any_base(offset) if isinstance(data, basestring): data = [int_any_base(d) for d in data.split(' ')] elif isinstance(data, list): data = data else: data = [int_any_base(data)] data = array.array('B', data) self._ipmi.write_fru_data(data, offset, fru_id)
def open_ipmi_aardvark_connection(self, port_or_serial, target_address, slave_address=0x20, routing_information=None, alias=None, enable_i2c_pullups=True): """Opens an Aardvark connection to the IPMB. `target_address` is the IPMB address to which the command should be sent. With the `serial_number` the aardvark device can be specified. If `None` is set the first is selected. """ target_address = int_any_base(target_address) slave_address = int_any_base(slave_address) if isinstance(port_or_serial, basestring) and '-' in port_or_serial: serial = port_or_serial port = None self._info('Opening Aardvark adapter with serial %s' % (port_or_serial, )) else: port = int(port_or_serial) serial = None self._info('Opening Aardvark adapter on port %d' % (port, )) interface = pyipmi.interfaces.create_interface( 'aardvark', slave_address=slave_address, port=port, serial_number=serial, enable_i2c_pullups=enable_i2c_pullups) ipmi = pyipmi.create_connection(interface) target = pyipmi.Target(target_address, routing_information) ipmi.target = target self._info('Opening IPMI aardvark connection to %02Xh' % target_address) connection = IpmiConnection(ipmi, target) self._active_connection = connection return self._cache.register(connection, alias)
def get_lan_interface_mac_address(self, channel): """Get MAC address for the channel. `channel` """ channel = int_any_base(channel) mac = self.get_lan_configuration_parameter( channel, pyipmi.lan.LAN_PARAMETER_MAC_ADDRESS) return misc.mac_address_to_string(mac)
def selected_sel_record_should_be_from_sensor_number(self, expected_number, msg=None): """Fails if the sensor number of the selected SEL record does not match the given sensor number. """ expected_number = int_any_base(expected_number) actual_number = self._selected_sel_record.sensor_number asserts.assert_equal(expected_number, actual_number, msg)
def set_lan_interface_ip_address(self, channel, ip_address): """Set IP address for the channel. `channel` """ channel = int_any_base(channel) ip_address = misc.parse_ip_address(ip_address) self.set_lan_configuration_parameter( channel, pyipmi.lan.LAN_PARAMETER_IP_ADDRESS, ip_address)
def set_lan_interface_gateway_ip_address(self, channel, ip_address): """Set the IP address of the interface channel. `channel` """ channel = int_any_base(channel) ip_address = misc.parse_ip_address(ip_address) self.set_lan_configuration_parameter(channel, pyipmi.lan.LAN_PARAMETER_DEFAULT_GATEWAY_ADDRESS, ip_address)
def get_lan_interface_mac_address(self, channel): """Get MAC address for the channel. `channel` """ channel = int_any_base(channel) mac = self.get_lan_configuration_parameter(channel, pyipmi.lan.LAN_PARAMETER_MAC_ADDRESS) return misc.mac_address_to_string(mac)
def set_lan_interface_ip_address(self, channel, ip_address): """Set IP address for the channel. `channel` """ channel = int_any_base(channel) ip_address = misc.parse_ip_address(ip_address) self.set_lan_configuration_parameter(channel, pyipmi.lan.LAN_PARAMETER_IP_ADDRESS, ip_address)
def wait_until_sensor_state_is(self, name, state, mask=0x7fff): """Wait until a sensor reaches the given state. `name` is the sensor ID string. See also `Get Sensor Reading`. """ state = int_any_base(state) mask = int_any_base(mask) start_time = time.time() while time.time() < start_time + self._timeout: current_state = self.get_sensor_state(name) if current_state & mask == state & mask: self._info('waited %s seconds until state "%s" was reached' % (time.time()-start_time, state)) return time.sleep(self._poll_interval) raise AssertionError('Sensor "%s" did not reach the state "%s" in %s.' % (name, state, utils.secs_to_timestr(self._timeout)))
def set_lan_interface_gateway_ip_address(self, channel, ip_address): """Set the IP address of the interface channel. `channel` """ channel = int_any_base(channel) ip_address = misc.parse_ip_address(ip_address) self.set_lan_configuration_parameter( channel, pyipmi.lan.LAN_PARAMETER_DEFAULT_GATEWAY_ADDRESS, ip_address)
def set_lan_interface_mac_address(self, channel, mac_address): """Set MAC address for the channel. `channel` `mac_address` """ channel = int_any_base(channel) mac_address = misc.parse_mac_address(mac_address) self.set_lan_configuration_parameter( channel, pyipmi.lan.LAN_PARAMETER_MAC_ADDRESS, mac_address)
def set_lan_interface_mac_address(self, channel, mac_address): """Set MAC address for the channel. `channel` `mac_address` """ channel = int_any_base(channel) mac_address = misc.parse_mac_address(mac_address) self.set_lan_configuration_parameter(channel, pyipmi.lan.LAN_PARAMETER_MAC_ADDRESS, mac_address)
def _find_hotswap_sdr_by_entity(self, entity): (entity_id, entity_instance) = entity.split(':') entity_id = find_entity_type_id(entity_id) entity_instance = int_any_base(entity_instance) if 'prefetched_hotswap_sdr' in self._cp: for name in self._cp['prefetched_hotswap_sdr']: hs_sdr = self._cp['prefetched_hotswap_sdr'][name] if hs_sdr.entity_id == entity_id and \ hs_sdr.entity_instance == entity_instance: return hs_sdr else: self._info('HS SDR not found')
def set_lan_interface_gateway_mac_address(self, channel, mac_address): """Set the MAC address of the interface channel's gateway. `channel` """ channel = int_any_base(channel) mac_address = misc.parse_mac_address(mac_address) mac_address = [b for b in reversed(mac_address)] self.set_lan_configuration_parameter( channel, pyipmi.lan.LAN_PARAMETER_DEFAULT_GATEWAY_MAC_ADDRESS, mac_address)
def set_lan_interface_gateway_mac_address(self, channel, mac_address): """Set the MAC address of the interface channel's gateway. `channel` """ channel = int_any_base(channel) mac_address = misc.parse_mac_address(mac_address) mac_address = [b for b in reversed(mac_address)] self.set_lan_configuration_parameter(channel, pyipmi.lan.LAN_PARAMETER_DEFAULT_GATEWAY_MAC_ADDRESS, mac_address)
def fru_data_get_picmg_multirecord_from_type(self, record_type, index=0, fru_id=0): """Returns the PICMG mulirecord specified by type. supported types are: `record_type`: Power Module Capability `index` specifies the index of the requested record. `fru_id` """ record_type = find_picmg_multirecord_id(record_type) index = int_any_base(index) fru_id = int_any_base(fru_id) fru = pyipmi.fru.FruInventory(self._fru_data(fru_id)) found_num = 0 for record in fru.multirecord_area.records: if ((record.record_type_id, record.picmg_record_type_id) == (pyipmi.fru.FruDataMultiRecord.TYPE_OEM_PICMG, record_type)): if found_num == index: return record raise AssertionError('Record type %s index=%s not found for fru_id=%s' % (record_type, index, fru_id))
def fru_data_tlv_at_offset_should_be(self, offset, expected_type, expected_length, expected_data, fru_id=0, msg=None): """Fails unless the FRU data contains the TLV triplet at the given offset.""" offset = int_any_base(offset) expected_type = find_fru_field_type_code(expected_type) expected_length = int_any_base(expected_length) fru_id = int(fru_id) # XXX: refactor this, pyipmi already has code for decoding TLVs if expected_type == 0: # binary expected_data = [int_any_base(d) for d in expected_data.split(' ')] else: expected_data = str(expected_data) expected_data = array.array('B', expected_data) tlv = array.array('B', self._fru_data(fru_id)[offset:offset+len(expected_data)+1]) asserts.assert_equal(expected_type, (tlv[0] >> 6) & 0x3, msg) asserts.assert_equal(expected_length, tlv[0] & 0x3f, msg) asserts.assert_equal(expected_data, tlv[1:], msg)
def set_lan_interface_ip_address_source(self, channel, source): """Set LAN Interface IP address source parameter: `channel` `source` The following sources are supported: UNSPECIFIED, STATIC, DHCP, BIOS_OR_SYSTEM_INTERFACE, BMC_OTHER_PROTOCOL """ channel = int_any_base(channel) source = find_lan_ip_source(source) self.set_lan_configuration_parameter( channel, pyipmi.lan.LAN_PARAMETER_IP_ADDRESS_SOURCE, (source, ))