async def test_workflow_connect_fail( data_store_mgr: DataStoreMgr, port_range, monkeypatch, caplog, ): """Simulate a failure during workflow connection. The data store should "rollback" any incidental changes made during the failed connection attempt by disconnecting from the workflow afterwards. Not an ideal test as we don't actually get a communication failure, the data store manager just skips contacting the workflow because we aren't providing a client for it to connect to, however, probably the best we can achieve without actually running a workflow. """ # patch the zmq logic so that the connection doesn't fail at the first # hurdle monkeypatch.setattr( 'cylc.flow.network.ZMQSocketBase._socket_bind', lambda *a, **k: None, ) # start a ZMQ REPLY socket in order to claim an unused port w_id = Tokens(user='******', workflow='workflow_id').id try: context = zmq.Context() server = ZMQSocketBase( zmq.REP, context=context, workflow=w_id, bind=True, ) server._socket_bind(*port_range) # register the workflow with the data store await data_store_mgr.register_workflow(w_id=w_id, is_active=False) contact_data = { 'name': 'workflow_id', 'owner': 'cylc', CFF.HOST: 'localhost', CFF.PORT: server.port, CFF.PUBLISH_PORT: server.port, CFF.API: 1 } # try to connect to the workflow caplog.set_level(logging.DEBUG, data_store_mgr.log.name) await data_store_mgr.connect_workflow(w_id, contact_data) # the connection should fail because our ZMQ socket is not a # WorkflowRuntimeServer with the correct endpoints and auth assert [record.message for record in caplog.records] == [ "[data-store] connect_workflow('~user/workflow_id', <dict>)", 'failed to connect to ~user/workflow_id', "[data-store] disconnect_workflow('~user/workflow_id')", ] finally: # tidy up server.stop() context.destroy()
def test_single_port(myflow, port_range): """Test server on a single port and port in use exception.""" context = zmq.Context() setup_keys(myflow) # auth keys are required for comms serv1 = ZMQSocketBase(zmq.REP, context=context, suite=myflow, bind=True) serv2 = ZMQSocketBase(zmq.REP, context=context, suite=myflow, bind=True) serv1._socket_bind(*port_range) port = serv1.port with pytest.raises(CylcError, match=r"Address already in use"): serv2._socket_bind(port, port) serv2.stop() serv1.stop() context.destroy()
def test_single_port(): """Test server on a single port and port in use exception.""" context = zmq.Context() create_auth_files('test_zmq') # auth keys are required for comms serv1 = ZMQSocketBase( zmq.REP, context=context, suite='test_zmq', bind=True) serv2 = ZMQSocketBase( zmq.REP, context=context, suite='test_zmq', bind=True) serv1._socket_bind(*PORT_RANGE) port = serv1.port with pytest.raises(CylcError, match=r"Address already in use") as exc: serv2._socket_bind(port, port) serv2.stop() serv1.stop() context.destroy()