def test_create_cq_ex_bad_flow(self): """ Test ibv_create_cq_ex() with wrong comp_vector / number of cqes """ for ctx, attr, attr_ex in self.devices: for i in range(10): cq_attrs_ex = CqInitAttrEx(cqe=0, wc_flags=0, comp_mask=0, flags=0) max_cqe = attr.max_cqe cq_attrs_ex.cqe = max_cqe + 1 + int(100 * random.random()) try: CQEX(ctx, cq_attrs_ex) except PyverbsRDMAError as ex: if ex.error_code == errno.EOPNOTSUPP: raise unittest.SkipTest('Create extended CQ is not supported') assert 'Failed to create extended CQ' in ex.args[0] assert ' Errno: 22' in ex.args[0] else: raise PyverbsError( 'Created a CQEX with {c} CQEs while device\'s max CQE={dc}'. format(c=cq_attrs_ex.cqe, dc=max_cqe)) comp_channel = random.randint(ctx.num_comp_vectors, 100) cq_attrs_ex.comp_vector = comp_channel cq_attrs_ex.cqe = get_num_cqes(attr) try: CQEX(ctx, cq_attrs_ex) except PyverbsRDMAError as ex: if ex.error_code == errno.EOPNOTSUPP: raise unittest.SkipTest('Create extended CQ is not supported') assert 'Failed to create extended CQ' in ex.args[0] assert ' Errno: 22' in ex.args[0] else: raise PyverbsError( 'Created a CQEX with comp_vector={c} while device\'s num_comp_vectors={dc}'. format(c=comp_channel, dc=ctx.num_comp_vectors))
def test_create_dm_bad_flow(self): """ test ibv_alloc_dm() with an illegal size and comp mask """ dm_len = self.attr_ex.max_dm_size + 1 dm_attrs = u.get_dm_attrs(dm_len) try: d.DM(self.ctx, dm_attrs) except PyverbsRDMAError as e: assert 'Failed to allocate device memory of size' in \ e.args[0] assert 'Max available size' in e.args[0] else: raise PyverbsError( 'Created a DM with size larger than max reported') dm_attrs.comp_mask = random.randint(1, 100) try: d.DM(self.ctx, dm_attrs) except PyverbsRDMAError as e: assert 'Failed to allocate device memory of size' in \ e.args[0] else: raise PyverbsError( 'Created a DM with illegal comp mask {c}'. \ format(c=dm_attrs.comp_mask))
def test_create_dm_bad_flow(self): """ test ibv_alloc_dm() with an illegal size and comp mask """ lst = d.get_device_list() for dev in lst: with d.Context(name=dev.name.decode()) as ctx: attr = ctx.query_device_ex() if attr.max_dm_size == 0: return dm_len = attr.max_dm_size + 1 dm_attrs = u.get_dm_attrs(dm_len) try: dm = d.DM(ctx, dm_attrs) except PyverbsRDMAError as e: assert 'Failed to allocate device memory of size' in e.args[ 0] assert 'Max available size' in e.args[0] else: raise PyverbsError( 'Created a DM with size larger than max reported') dm_attrs.comp_mask = random.randint(1, 100) try: dm = d.DM(ctx, dm_attrs) except PyverbsRDMAError as e: assert 'Failed to allocate device memory of size' in e.args[ 0] else: raise PyverbsError('Created a DM with illegal comp mask {c}'.\ format(c=dm_attrs.comp_mask))
def test_create_cq_ex_bad_flow(self): """ Test ibv_create_cq_ex() with wrong comp_vector / number of cqes """ for ctx, attr, attr_ex in self.devices: for i in range(10): cq_attrs_ex = get_attrs_ex(attr, attr_ex) max_cqe = attr.max_cqe cq_attrs_ex.cqe = max_cqe + 1 + int(100 * random.random()) try: CQEX(ctx, cq_attrs_ex) except PyverbsError as e: assert 'Failed to create extended CQ' in e.args[0] assert ' Errno: 22' in e.args[0] else: raise PyverbsError( 'Created a CQEX with {c} CQEs while device\'s max CQE={dc}' .format(c=cq_attrs_ex.cqe, dc=max_cqe)) comp_channel = random.randint(ctx.num_comp_vectors, 100) cq_attrs_ex.comp_vector = comp_channel cq_attrs_ex.cqe = get_num_cqes(attr) try: CQEX(ctx, cq_attrs_ex) except PyverbsError as e: assert 'Failed to create extended CQ' in e.args[0] assert ' Errno: 22' in e.args[0] else: raise PyverbsError( 'Created a CQEX with comp_vector={c} while device\'s num_comp_vectors={dc}' .format(c=comp_channel, dc=ctx.num_comp_vectors))
def test_create_cq_bad_flow(self): """ Test ibv_create_cq() with a wrong comp_vector / cqe number """ for ctx, attr, attr_ex in self.devices: for i in range(10): cc = CompChannel(ctx) cqes = 100 comp_vector = ctx.num_comp_vectors + int(100 * random.random()) has_cc = random.choice([True, False]) if not has_cc: cc = None try: with CQ(ctx, cqes, None, cc, comp_vector): pass except PyverbsError as e: assert 'Failed to create a CQ' in e.args[0] assert 'Invalid argument' in e.args[0] else: raise PyverbsError( 'Created a CQ with comp_vector={n} while device\'s num_comp_vectors={nc}' .format(n=comp_vector, nc=ctx.num_comp_vectors)) max_cqe = ctx.query_device().max_cqe cqes = random.randint(max_cqe + 1, max_cqe + 100) try: with CQ(ctx, cqes, None, cc, 0): pass except PyverbsError as err: assert 'Failed to create a CQ' in err.args[0] assert 'Invalid argument' in err.args[0] else: raise PyverbsError( 'Created a CQ with cqe={n} while device\'s max_cqe={nc}' .format(n=cqes, nc=max_cqe))
def validate_atomic(opcode, recv_player, send_player, receiver_val, send_cmp_add, send_swp): """ Validate the data after atomic operations. The expected data in each side of traffic depends on the atomic type and the sender SendWR values. :param opcode: The atomic opcode. :param recv_player: The receiver player. :param send_player: The sender player. :param receiver_val: The value on the receiver MR before the atomic action. :param send_cmp_add: The send WR compare/add value depende on the atomic type. :param send_swp: The send WR swap value, used only in atomic compare and swap. """ send_expected = receiver_val if opcode in [e.IBV_WR_ATOMIC_CMP_AND_SWP, e.IBV_QP_EX_WITH_ATOMIC_CMP_AND_SWP]: recv_expected = send_swp if receiver_val == send_cmp_add \ else receiver_val if opcode in [e.IBV_WR_ATOMIC_FETCH_AND_ADD, e.IBV_QP_EX_WITH_ATOMIC_FETCH_AND_ADD]: recv_expected = receiver_val + send_cmp_add send_actual = int.from_bytes(send_player.mr.read(length=8, offset=0), byteorder='big') recv_actual = int.from_bytes(recv_player.mr.read(length=8, offset=0), byteorder='big') if send_actual != int8b_from_int(send_expected): raise PyverbsError( 'Atomic sender data validation failed: expected {exp}, received {rcv}'. format(exp=int8b_from_int(send_expected), rcv=send_actual)) if recv_actual != int8b_from_int(recv_expected): raise PyverbsError( 'Atomic reciver data validation failed: expected {exp}, received {rcv}'. format(exp=int8b_from_int(recv_expected), rcv=recv_actual))
def test_create_cq_ex_bad_flow(): """ Test ibv_create_cq_ex() with wrong comp_vector / number of cqes """ lst = d.get_device_list() for dev in lst: with d.Context(name=dev.name.decode()) as ctx: attrs_ex = get_attrs_ex(ctx) max_cqe = ctx.query_device().max_cqe attrs_ex.cqe = max_cqe + random.randint(1, 100) try: CQEX(ctx, attrs_ex) except PyverbsError as e: assert 'Failed to create extended CQ' in e.args[0] assert ' Errno: 22' in e.args[0] else: raise PyverbsError( 'Created a CQEX with {c} CQEs while device\'s max CQE={dc}' .format(c=attrs_ex.cqe, dc=max_cqe)) comp_channel = random.randint(ctx.num_comp_vectors, 100) attrs_ex.comp_vector = comp_channel attrs_ex.cqe = get_num_cqes(ctx) try: CQEX(ctx, attrs_ex) except PyverbsError as e: assert 'Failed to create extended CQ' in e.args[0] assert ' Errno: 22' in e.args[0] else: raise PyverbsError( 'Created a CQEX with comp_vector={c} while device\'s num_comp_vectors={dc}' .format(c=comp_channel, dc=ctx.num_comp_vectors))
def check_after_traffic(self): if self.bad_flow == DCI_TEST_BAD_FLOW_WITH_RESET: for errs in self.qp_stream_errors: if errs[0] != errs[1]: msg = f'Number of qp_stream_errors {errs[0]} not same '\ f'as number of catches {errs[1]}' raise PyverbsError(msg) if self.stream_check: msg = 'Reset of good stream id does not create exception' raise PyverbsError(msg)
def test_create_ah_roce(self): """ Verify that AH can't be created without GRH in RoCE """ done = 0 for ctx, attr, attr_ex in self.devices: pd = PD(ctx) for port_num in range(1, 1 + attr.phys_port_cnt): port_attr = ctx.query_port(port_num) if port_attr.state != e.IBV_PORT_ACTIVE and \ port_attr.state != e.IBV_PORT_INIT: continue if port_attr.link_layer == e.IBV_LINK_LAYER_INFINIBAND: raise unittest.SkipTest( 'Can\'t run RoCE tests on IB link layer') ah_attr = AHAttr(is_global=0, port_num=port_num) try: ah = AH(pd, attr=ah_attr) except PyverbsError as err: assert 'Failed to create AH' in err.args[0] done += 1 else: raise PyverbsError('Created a non-global AH on RoCE') if done == 0: raise unittest.SkipTest('No port is up, can\'t create AH')
def poll_cq_ex(self, cqex, is_server=True, to_valid=True): start = time.perf_counter() poll_attr = PollCqAttr() ret = cqex.start_poll(poll_attr) while ret == 2 and (time.perf_counter() - start < u.POLL_CQ_TIMEOUT): ret = cqex.start_poll(poll_attr) if ret != 0: raise PyverbsRDMAErrno('Failed to poll CQ - got a timeout') if cqex.status != e.IBV_WC_SUCCESS: raise PyverbsError(f'Completion status is {cqex.status}') actual_cqe_dict = {} if to_valid: recv_flags = cqex.read_wc_flags() recv_opcode = cqex.read_opcode() actual_cqe_dict = {'wr_id': cqex.wr_id, 'opcode': cqex.read_opcode(), 'wc_flags': cqex.read_wc_flags()} if is_server: actual_cqe_dict['tag'] = cqex.read_tm_info().tag if recv_opcode == e.IBV_WC_TM_RECV and not \ (recv_flags & (e.IBV_WC_TM_MATCH | e.IBV_WC_TM_DATA_VALID)): # In case of receiving unexpected tag, HW doesn't return such wc_flags # updadte unexpected count and sync is required. self.server.unexp_cnt += 1 cqex.end_poll() self.post_sync() return actual_cqe_dict if recv_opcode == e.IBV_WC_TM_ADD and (recv_flags & e.IBV_WC_TM_SYNC_REQ): # These completion is complemented by the IBV_WC_TM_SYNC_REQ flag, # which indicates whether further HW synchronization is needed. cqex.end_poll() self.post_sync() return actual_cqe_dict cqex.end_poll() return actual_cqe_dict
def mixed_traffic(self): s_recv_wr = u.get_recv_wr(self.server) u.post_recv(self.server, s_recv_wr) self.prepare_send_elements() for i in range(self.iters): self.client.qp.wr_start() if i % 2: self.client.mr.write('c' * self.client.mr.length, self.client.mr.length) self.client.qp.wr_flags = e.IBV_SEND_SIGNALED self.client.qp.wr_send() self.client.qp.wr_set_sge(self.regular_send_sge) else: self.client.mr.write('s' * self.client.mr.length, self.client.mr.length) self.client.qp.wr_raw_wqe(self.raw_send_wqe) self.client.qp.wr_complete() u.poll_cq_ex(self.client.cq) u.poll_cq_ex(self.server.cq) u.post_recv(self.server, s_recv_wr) if not i % 2 and self.client.cq.read_opcode() != e.IBV_WC_DRIVER2: raise PyverbsError( 'Opcode validation failed: expected ' f'{e.IBV_WC_DRIVER2}, received {self.client.cq.read_opcode()}' ) act_buffer = self.server.mr.read(self.server.mr.length, 0) u.validate(act_buffer, i % 2, self.server.mr.length)
def test_dm_write_bad_flow(self): """ Test writing to the device memory with bad offset and length """ lst = d.get_device_list() for dev in lst: with d.Context(name=dev.name.decode()) as ctx: attr = ctx.query_device_ex() if attr.max_dm_size == 0: return dm_len = random.randrange(u.MIN_DM_SIZE, attr.max_dm_size, u.DM_ALIGNMENT) dm_attrs = u.get_dm_attrs(dm_len) with d.DM(ctx, dm_attrs) as dm: data_length = random.randrange(4, dm_len, u.DM_ALIGNMENT) data_offset = random.randrange(0, dm_len - data_length, u.DM_ALIGNMENT) data_offset += 1 # offset needs to be a multiple of 4 data = u.get_data(data_length) try: dm.copy_to_dm(data_offset, data.encode(), data_length) except PyverbsRDMAError as e: assert 'Failed to copy to dm' in e.args[0] else: raise PyverbsError( 'Wrote to device memory with a bad offset')
def raw_traffic(client, server, iters, l3=PacketConsts.IP_V4, l4=PacketConsts.UDP_PROTO): """ Runs raw ethernet traffic between two sides :param client: client side, clients base class is BaseTraffic :param server: server side, servers base class is BaseTraffic :param iters: number of traffic iterations :param l3: Packet layer 3 type: 4 for IPv4 or 6 for IPv6 :param l4: Packet layer 4 type: 'tcp' or 'udp' :return: """ s_recv_wr = get_recv_wr(server) c_recv_wr = get_recv_wr(client) for qp_idx in range(server.qp_count): # prepare the receive queue with RecvWR post_recv(client, c_recv_wr, qp_idx=qp_idx) post_recv(server, s_recv_wr, qp_idx=qp_idx) read_offset = 0 for _ in range(iters): for qp_idx in range(server.qp_count): c_send_wr, c_sg, msg = get_send_elements_raw_qp(client, l3, l4) send(client, c_send_wr, e.IBV_WR_SEND, False, qp_idx) poll_cq(client.cq) poll_cq(server.cq) post_recv(server, s_recv_wr, qp_idx=qp_idx) msg_received = server.mr.read(server.msg_size, read_offset) # Validate received packet if msg_received[0:server.msg_size] != msg[0:client.msg_size]: raise PyverbsError( f'Data validation failure: expected {msg}, received {msg_received}' )
def test_create_ah_roce(self): """ Verify that AH can't be created without GRH in RoCE """ done = 0 for ctx, attr, attr_ex in self.devices: pd = PD(ctx) for port_num in range(1, 1 + attr.phys_port_cnt): port_attr = ctx.query_port(port_num) if port_attr.state != e.IBV_PORT_ACTIVE and \ port_attr.state != e.IBV_PORT_INIT: continue if port_attr.link_layer != e.IBV_LINK_LAYER_ETHERNET: raise unittest.SkipTest('RoCE tests are only supported on Ethernet link layer') ah_attr = AHAttr(is_global=0, port_num=port_num) try: ah = AH(pd, attr=ah_attr) except PyverbsRDMAError as ex: if ex.error_code == errno.EOPNOTSUPP: raise unittest.SkipTest('Create AH is not supported') assert 'Failed to create AH' in str(ex) done +=1 else: raise PyverbsError('Created a non-global AH on RoCE') if done == 0: raise unittest.SkipTest('No port is up, can\'t create AH')
def event_handler(agr_obj): """ Handle and execute corresponding API for RDMACM events of asynchronous communication :param agr_obj: Aggregation object which contains all necessary resources :return: None """ cm_event = CMEvent(agr_obj.cmid.event_channel) if cm_event.event_type == ce.RDMA_CM_EVENT_ADDR_RESOLVED: agr_obj.cmid.resolve_route() elif cm_event.event_type == ce.RDMA_CM_EVENT_ROUTE_RESOLVED: agr_obj.create_qp() param = agr_obj.create_conn_param() if agr_obj.with_ext_qp: param.qpn = agr_obj.qp.qp_num agr_obj.cmid.connect(param) elif cm_event.event_type == ce.RDMA_CM_EVENT_CONNECT_REQUEST: agr_obj.create_child_id(cm_event) param = agr_obj.create_conn_param() agr_obj.create_qp() if agr_obj.with_ext_qp: agr_obj.modify_ext_qp_to_rts() param.qpn = agr_obj.qp.qp_num agr_obj.child_id.accept(param) elif cm_event.event_type == ce.RDMA_CM_EVENT_ESTABLISHED: agr_obj.connected = True elif cm_event.event_type == ce.RDMA_CM_EVENT_CONNECT_RESPONSE: agr_obj.connected = True if agr_obj.with_ext_qp: agr_obj.modify_ext_qp_to_rts() agr_obj.cmid.establish() elif cm_event.event_type == ce.RDMA_CM_EVENT_DISCONNECTED: if agr_obj.is_server: agr_obj.child_id.disconnect() agr_obj.connected = False else: agr_obj.cmid.disconnect() agr_obj.connected = False else: if cm_event.event_type in events_dict: raise PyverbsError('Unexpected event - {}'.format( events_dict[cm_event.event_type])) else: raise PyverbsError('The event {} is not supported'.format( cm_event.event_type)) cm_event.ack_cm_event()
def verify_cqe(self, actual_cqe, wr_id=0, opcode=None, wc_flags=0, tag=0, is_server=True): expected_cqe = {'wr_id': wr_id, 'opcode': opcode, 'wc_flags': wc_flags} if is_server: expected_cqe['tag'] = tag for key in expected_cqe: if expected_cqe[key] != actual_cqe[key]: raise PyverbsError(f'CQE validation failure: {key} expected value: ' f'{expected_cqe[key]}, received {actual_cqe[key]}')
def bad_flow_handler_qp(self, qp_idx, ex, reset=False): str_id = self.get_stream_id(qp_idx) bt_stream = (1 << str_id) if isinstance(ex, PyverbsRDMAError): if ex.error_code == e.IBV_WC_LOC_PROT_ERR: self.qp_stream_errors[qp_idx][1] += 1 if (self.qp_stream_errors[qp_idx][0] & bt_stream) != 0: raise PyverbsError(f'Dublicate error from stream id {str_id}') self.qp_stream_errors[qp_idx][0] |= bt_stream if ex.error_code == e.IBV_WC_WR_FLUSH_ERR: qp_attr, _ = self.qps[qp_idx].query(e.IBV_QP_STATE) if qp_attr.cur_qp_state == e.IBV_QPS_ERR and reset: if self.qp_stream_errors[qp_idx][1] != self.dcis[qp_idx]['errored']: msg = f'QP {qp_idx} in ERR state with wrong number of counter' raise PyverbsError(msg) self.reset_qp(qp_idx) self.qp_stream_errors[qp_idx][2] = True return True
def test_create_cq_bad_flow(): """ Test ibv_create_cq() with a wrong comp_vector / cqe number """ lst = d.get_device_list() for dev in lst: with d.Context(name=dev.name.decode()) as ctx: cqes = get_num_cqes(ctx) comp_vector = random.randint(ctx.num_comp_vectors, 100) try: if random.choice([True, False]): with CompChannel(ctx) as cc: with CQ(ctx, cqes, None, cc, comp_vector): pass else: with CQ(ctx, cqes, None, None, comp_vector): pass except PyverbsError as e: assert 'Failed to create a CQ' in e.args[0] assert 'Invalid argument' in e.args[0] else: raise PyverbsError( 'Created a CQ with comp_vector={n} while device\'s num_comp_vectors={nc}' .format(n=comp_vector, nc=ctx.num_comp_vectors)) max_cqe = ctx.query_device().max_cqe cqes = random.randint(max_cqe + 1, max_cqe + 100) try: if random.choice([True, False]): with CompChannel(ctx) as cc: with CQ(ctx, cqes, None, cc, 0): pass else: with CQ(ctx, cqes, None, None, 0): pass except PyverbsError as err: assert 'Failed to create a CQ' in err.args[0] assert 'Invalid argument' in err.args[0] else: raise PyverbsError( 'Created a CQ with cqe={n} while device\'s max_cqe={nc}' .format(n=cqes, nc=max_cqe))
def test_reg_mw_wrong_type(self): """ Test ibv_alloc_mw() """ for ctx, attr, attr_ex in self.devices: with PD(ctx) as pd: try: mw_type = random.randint(3, 100) MW(pd, mw_type) except PyverbsRDMAError: pass else: raise PyverbsError('Created a MW with type {t}'.\ format(t=mw_type))
def two_nodes_rdmacm_traffic(self, connection_resources, test_flow, **resource_kwargs): """ Init and manage the rdmacm test processes. If needed, terminate those processes and raise an exception. :param connection_resources: The CMConnection resources to use. :param test_flow: The target RDMACM flow method to run. :param resource_kwargs: Dict of args that specify the CMResources specific attributes. Each test case can pass here as key words the specific CMResources attributes that are requested. :return: None """ if resource_kwargs.get('port_space', None) == ce.RDMA_PS_UDP and \ self.is_eth_and_has_roce_hw_bug(): raise unittest.SkipTest( 'Device {} doesn\'t support UDP with RoCEv2'.format( self.dev_name)) ctx = mp.get_context('fork') self.syncer = ctx.Barrier(NUM_OF_PROCESSES, timeout=15) self.notifier = ctx.Queue() passive = ctx.Process(target=test_flow, kwargs={ 'connection_resources': connection_resources, 'passive': True, **resource_kwargs }) active = ctx.Process(target=test_flow, kwargs={ 'connection_resources': connection_resources, 'passive': False, **resource_kwargs }) passive.start() active.start() passive.join(15) active.join(15) # If the processes is still alive kill them and fail the test. proc_killed = False for proc in [passive, active]: if proc.is_alive(): proc.terminate() proc_killed = True # Check if the test processes raise exceptions. if not self.notifier.empty(): res = self.notifier.get() if res is not None: raise PyverbsError(res) # Raise exeption if the test proceses was terminate. if proc_killed: raise Exception('RDMA CM test procces is stuck, kill the test')
def test_reg_mw_wrong_type(self): """ Test ibv_alloc_mw() """ lst = d.get_device_list() for dev in lst: with d.Context(name=dev.name.decode()) as ctx: with PD(ctx) as pd: try: mw_type = random.randint(3, 100) mw = MW(pd, mw_type) except PyverbsRDMAError as e: pass else: raise PyverbsError('Created a MW with type {t}'.\ format(t=mw_type))
def test_reg_mw_wrong_type(self): """ Verify that trying to create a MW of a wrong type fails """ for ctx, attr, attr_ex in self.devices: with PD(ctx) as pd: try: mw_type = random.randint(3, 100) MW(pd, mw_type) except PyverbsRDMAError: pass else: raise PyverbsError('Created a MW with type {t}'.\ format(t=mw_type))
def test_reg_mw_wrong_type(self): """ Verify that trying to create a MW of a wrong type fails """ with d.Context(name=self.dev_name) as ctx: with PD(ctx) as pd: try: mw_type = 3 MW(pd, mw_type) except PyverbsRDMAError as ex: if ex.error_code == errno.EOPNOTSUPP: raise unittest.SkipTest('Create memory window of type {} is not supported'.format(mw_type)) else: raise PyverbsError('Created a MW with type {t}'.\ format(t=mw_type))
def event_handler(self, expected_event=None): """ Handle and execute corresponding API for RDMACM events of asynchronous communication. :param expected_event: The user expected event. :return: None """ cm_event = CMEvent(self.cm_res.cmid.event_channel) if cm_event.event_type == ce.RDMA_CM_EVENT_CONNECT_REQUEST: self.cm_res.create_child_id(cm_event) if expected_event and expected_event != cm_event.event_type: raise PyverbsError( 'Expected this event: {}, got this event: {}'.format( expected_event, cm_event.event_str())) cm_event.ack_cm_event()
def test_create_ah_roce(self): """ Verify that AH can't be created without GRH in RoCE """ self.verify_link_layer_ether(self.ctx) self.verify_state(self.ctx) pd = PD(self.ctx) ah_attr = AHAttr(is_global=0, port_num=self.ib_port) try: AH(pd, attr=ah_attr) except PyverbsRDMAError as ex: if ex.error_code == errno.EOPNOTSUPP: raise unittest.SkipTest('Create AH is not supported') assert 'Failed to create AH' in str(ex) else: raise PyverbsError(f'Successfully created a non-global AH on RoCE port={self.ib_port}')
def test_create_ah_roce(self): """ Verify that AH can't be created without GRH in RoCE """ for ctx, attr, attr_ex in self.devices: pd = PD(ctx) for port_num in range(1, 1 + attr.phys_port_cnt): port_attr = ctx.query_port(port_num) if port_attr.link_layer == e.IBV_LINK_LAYER_INFINIBAND: return ah_attr = AHAttr(is_global=0, port_num=port_num) try: ah = AH(pd, attr=ah_attr) except PyverbsError as err: assert 'Failed to create AH' in err.args[0] else: raise PyverbsError('Created a non-global AH on RoCE')
def test_reg_mw_wrong_type(self): """ Verify that trying to create a MW of a wrong type fails """ for ctx, attr, attr_ex in self.devices: with PD(ctx) as pd: try: mw_type = random.randint(3, 100) MW(pd, mw_type) except PyverbsRDMAError as ex: if ex.error_code == errno.EOPNOTSUPP: raise unittest.SkipTest( 'Create memory window of type {} is not supported'. format(mw_type)) else: raise PyverbsError('Created a MW with type {t}'.\ format(t=mw_type))
def test_dm_write_bad_flow(self): """ Test writing to the device memory with bad offset and length """ dm_len = random.randrange(u.MIN_DM_SIZE, self.attr_ex.max_dm_size / 2, u.DM_ALIGNMENT) dm_attrs = u.get_dm_attrs(dm_len) with d.DM(self.ctx, dm_attrs) as dm: data_length = random.randrange(4, dm_len, u.DM_ALIGNMENT) data_offset = random.randrange(0, dm_len - data_length, u.DM_ALIGNMENT) data_offset += 1 # offset needs to be a multiple of 4 data = 'a' * data_length try: dm.copy_to_dm(data_offset, data.encode(), data_length) except PyverbsRDMAError as e: assert 'Failed to copy to dm' in e.args[0] else: raise PyverbsError('Wrote to device memory with a bad offset')
def event_handler(self, expected_event=None): """ Handle and execute corresponding API for RDMACM events of asynchronous communication. :param expected_event: The user expected event. :return: None """ cm_event = CMEvent(self.cm_res.cmid.event_channel) if cm_event.event_type == ce.RDMA_CM_EVENT_CONNECT_REQUEST: self.cm_res.create_child_id(cm_event) elif cm_event.event_type in [ce.RDMA_CM_EVENT_ESTABLISHED, ce.RDMA_CM_EVENT_MULTICAST_JOIN]: self.cm_res.set_ud_params(cm_event) if expected_event and expected_event != cm_event.event_type: raise PyverbsError('Expected this event: {}, got this event: {}'. format(expected_event, cm_event.event_str())) if expected_event == ce.RDMA_CM_EVENT_REJECTED: assert cm_event.private_data == REJECT_MSG, \ f'CM event data ({cm_event.private_data}) is different than the expected ({REJECT_MSG})' cm_event.ack_cm_event()
def test_rdmacm_sync_traffic(self): syncer = mp.Barrier(2, timeout=5) notifier = mp.Queue() passive = mp.Process(target=passive_side, args=[self.ip_addr, syncer, notifier]) active = mp.Process(target=active_side, args=[self.ip_addr, syncer, notifier]) passive.start() active.start() while notifier.empty(): pass for _ in range(2): res = notifier.get() if res is not None: passive.terminate() active.terminate() raise PyverbsError(res) passive.join() active.join()