Fixing lots of tests.
This commit is contained in:
parent
15653ef1f1
commit
2dbd90d415
9 changed files with 214 additions and 192 deletions
|
|
@ -113,7 +113,8 @@ OPTION_CLASSES = None
|
||||||
PROCESS_ID = None
|
PROCESS_ID = None
|
||||||
|
|
||||||
TWISTED_APPLICATION = None
|
TWISTED_APPLICATION = None
|
||||||
EVENNIA_SERVICE = None
|
EVENNIA_PORTAL_SERVICE = None
|
||||||
|
EVENNIA_SERVER_SERVICE = None
|
||||||
|
|
||||||
|
|
||||||
def _create_version():
|
def _create_version():
|
||||||
|
|
@ -150,6 +151,7 @@ _LOADED = False
|
||||||
|
|
||||||
PORTAL_MODE = False
|
PORTAL_MODE = False
|
||||||
|
|
||||||
|
|
||||||
def _init(portal_mode=False):
|
def _init(portal_mode=False):
|
||||||
"""
|
"""
|
||||||
This function is called automatically by the launcher only after
|
This function is called automatically by the launcher only after
|
||||||
|
|
@ -172,7 +174,7 @@ def _init(portal_mode=False):
|
||||||
global settings, lockfuncs, logger, utils, gametime, ansi, spawn, managers
|
global settings, lockfuncs, logger, utils, gametime, ansi, spawn, managers
|
||||||
global contrib, TICKER_HANDLER, MONITOR_HANDLER, SESSION_HANDLER, PROCESS_ID
|
global contrib, TICKER_HANDLER, MONITOR_HANDLER, SESSION_HANDLER, PROCESS_ID
|
||||||
global TASK_HANDLER, PORTAL_SESSION_HANDLER, SERVER_SESSION_HANDLER
|
global TASK_HANDLER, PORTAL_SESSION_HANDLER, SERVER_SESSION_HANDLER
|
||||||
global GLOBAL_SCRIPTS, OPTION_CLASSES, EVENNIA_SERVICE, TWISTED_APPLICATION
|
global GLOBAL_SCRIPTS, OPTION_CLASSES, EVENNIA_PORTAL_SERVICE, EVENNIA_SERVER_SERVICE, TWISTED_APPLICATION
|
||||||
global EvMenu, EvTable, EvForm, EvMore, EvEditor
|
global EvMenu, EvTable, EvForm, EvMore, EvEditor
|
||||||
global ANSIString, FuncParser
|
global ANSIString, FuncParser
|
||||||
global AttributeProperty, TagProperty, TagCategoryProperty, ServerConfig
|
global AttributeProperty, TagProperty, TagCategoryProperty, ServerConfig
|
||||||
|
|
@ -247,6 +249,7 @@ def _init(portal_mode=False):
|
||||||
PROCESS_ID = os.getpid()
|
PROCESS_ID = os.getpid()
|
||||||
|
|
||||||
from twisted.application.service import Application
|
from twisted.application.service import Application
|
||||||
|
|
||||||
TWISTED_APPLICATION = Application("Evennia")
|
TWISTED_APPLICATION = Application("Evennia")
|
||||||
|
|
||||||
_evennia_service_class = None
|
_evennia_service_class = None
|
||||||
|
|
@ -254,13 +257,17 @@ def _init(portal_mode=False):
|
||||||
if portal_mode:
|
if portal_mode:
|
||||||
# Set up the PortalSessionHandler
|
# Set up the PortalSessionHandler
|
||||||
from evennia.server.portal import portalsessionhandler
|
from evennia.server.portal import portalsessionhandler
|
||||||
|
|
||||||
portal_sess_handler_class = class_from_module(settings.PORTAL_SESSION_HANDLER_CLASS)
|
portal_sess_handler_class = class_from_module(settings.PORTAL_SESSION_HANDLER_CLASS)
|
||||||
portalsessionhandler.PORTAL_SESSIONS = portal_sess_handler_class()
|
portalsessionhandler.PORTAL_SESSIONS = portal_sess_handler_class()
|
||||||
SESSION_HANDLER = portalsessionhandler.PORTAL_SESSIONS
|
SESSION_HANDLER = portalsessionhandler.PORTAL_SESSIONS
|
||||||
evennia.PORTAL_SESSION_HANDLER = evennia.SESSION_HANDLER
|
evennia.PORTAL_SESSION_HANDLER = evennia.SESSION_HANDLER
|
||||||
_evennia_service_class = class_from_module(settings.EVENNIA_PORTAL_SERVICE_CLASS)
|
_evennia_service_class = class_from_module(settings.EVENNIA_PORTAL_SERVICE_CLASS)
|
||||||
|
EVENNIA_PORTAL_SERVICE = _evennia_service_class()
|
||||||
|
EVENNIA_PORTAL_SERVICE.setServiceParent(TWISTED_APPLICATION)
|
||||||
|
|
||||||
from django.db import connection
|
from django.db import connection
|
||||||
|
|
||||||
# we don't need a connection to the database so close it right away
|
# we don't need a connection to the database so close it right away
|
||||||
try:
|
try:
|
||||||
connection.close()
|
connection.close()
|
||||||
|
|
@ -277,9 +284,8 @@ def _init(portal_mode=False):
|
||||||
SESSION_HANDLER = sessionhandler.SESSIONS
|
SESSION_HANDLER = sessionhandler.SESSIONS
|
||||||
SERVER_SESSION_HANDLER = SESSION_HANDLER
|
SERVER_SESSION_HANDLER = SESSION_HANDLER
|
||||||
_evennia_service_class = class_from_module(settings.EVENNIA_SERVER_SERVICE_CLASS)
|
_evennia_service_class = class_from_module(settings.EVENNIA_SERVER_SERVICE_CLASS)
|
||||||
|
EVENNIA_SERVER_SERVICE = _evennia_service_class()
|
||||||
EVENNIA_SERVICE = _evennia_service_class()
|
EVENNIA_SERVER_SERVICE.setServiceParent(TWISTED_APPLICATION)
|
||||||
EVENNIA_SERVICE.setServiceParent(TWISTED_APPLICATION)
|
|
||||||
|
|
||||||
# API containers
|
# API containers
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -230,23 +230,23 @@ class AMPServerClientProtocol(amp.AMPMultiConnectionProtocol):
|
||||||
# force a resync of sessions from the portal side. This happens on
|
# force a resync of sessions from the portal side. This happens on
|
||||||
# first server-connect.
|
# first server-connect.
|
||||||
server_restart_mode = kwargs.get("server_restart_mode", "shutdown")
|
server_restart_mode = kwargs.get("server_restart_mode", "shutdown")
|
||||||
evennia.EVENNIA_SERVICE.run_init_hooks(server_restart_mode)
|
evennia.EVENNIA_SERVER_SERVICE.run_init_hooks(server_restart_mode)
|
||||||
evennia.SERVER_SESSION_HANDLER.portal_sessions_sync(kwargs.get("sessiondata"))
|
evennia.SERVER_SESSION_HANDLER.portal_sessions_sync(kwargs.get("sessiondata"))
|
||||||
evennia.SERVER_SESSION_HANDLER.portal_start_time = kwargs.get("portal_start_time")
|
evennia.SERVER_SESSION_HANDLER.portal_start_time = kwargs.get("portal_start_time")
|
||||||
|
|
||||||
elif operation == amp.SRELOAD: # server reload
|
elif operation == amp.SRELOAD: # server reload
|
||||||
# shut down in reload mode
|
# shut down in reload mode
|
||||||
evennia.SERVER_SESSION_HANDLER.all_sessions_portal_sync()
|
evennia.SERVER_SESSION_HANDLER.all_sessions_portal_sync()
|
||||||
evennia.EVENNIA_SERVICE.shutdown(mode="reload")
|
evennia.EVENNIA_SERVER_SERVICE.shutdown(mode="reload")
|
||||||
|
|
||||||
elif operation == amp.SRESET:
|
elif operation == amp.SRESET:
|
||||||
# shut down in reset mode
|
# shut down in reset mode
|
||||||
evennia.SERVER_SESSION_HANDLER.all_sessions_portal_sync()
|
evennia.SERVER_SESSION_HANDLER.all_sessions_portal_sync()
|
||||||
evennia.EVENNIA_SERVICE.shutdown(mode="reset")
|
evennia.EVENNIA_SERVER_SERVICE.shutdown(mode="reset")
|
||||||
|
|
||||||
elif operation == amp.SSHUTD: # server shutdown
|
elif operation == amp.SSHUTD: # server shutdown
|
||||||
# shutdown in stop mode
|
# shutdown in stop mode
|
||||||
evennia.EVENNIA_SERVICE.shutdown(mode="shutdown")
|
evennia.EVENNIA_SERVER_SERVICE.shutdown(mode="shutdown")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise Exception("operation %(op)s not recognized." % {"op": operation})
|
raise Exception("operation %(op)s not recognized." % {"op": operation})
|
||||||
|
|
|
||||||
|
|
@ -174,6 +174,8 @@ def reset_server():
|
||||||
also checks so the warm-reset mechanism works as it should.
|
also checks so the warm-reset mechanism works as it should.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
if settings._TEST_ENVIRONMENT:
|
||||||
|
return
|
||||||
ServerConfig.objects.conf("server_epoch", time.time())
|
ServerConfig.objects.conf("server_epoch", time.time())
|
||||||
|
|
||||||
logger.log_info("Initial setup complete. Restarting Server once.")
|
logger.log_info("Initial setup complete. Restarting Server once.")
|
||||||
|
|
@ -191,12 +193,6 @@ def handle_setup(last_step=None):
|
||||||
the function will exit immediately.
|
the function will exit immediately.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if last_step in ("done", -1):
|
|
||||||
# this means we don't need to handle setup since
|
|
||||||
# it already ran sucessfully once. -1 is the legacy
|
|
||||||
# value for existing databases.
|
|
||||||
return
|
|
||||||
|
|
||||||
# setup sequence
|
# setup sequence
|
||||||
setup_sequence = {
|
setup_sequence = {
|
||||||
"create_objects": create_objects,
|
"create_objects": create_objects,
|
||||||
|
|
@ -205,6 +201,12 @@ def handle_setup(last_step=None):
|
||||||
"done": reset_server,
|
"done": reset_server,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if last_step in ("done", -1):
|
||||||
|
# this means we don't need to handle setup since
|
||||||
|
# it already ran sucessfully once. -1 is the legacy
|
||||||
|
# value for existing databases.
|
||||||
|
return
|
||||||
|
|
||||||
# determine the sequence so we can skip ahead
|
# determine the sequence so we can skip ahead
|
||||||
steps = list(setup_sequence)
|
steps = list(setup_sequence)
|
||||||
steps = steps[steps.index(last_step) + 1 if last_step is not None else 0 :]
|
steps = steps[steps.index(last_step) + 1 if last_step is not None else 0 :]
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,7 @@ class PortalSessionHandler(SessionHandler):
|
||||||
now = time.time()
|
now = time.time()
|
||||||
if (
|
if (
|
||||||
now - self.connection_last < _MIN_TIME_BETWEEN_CONNECTS
|
now - self.connection_last < _MIN_TIME_BETWEEN_CONNECTS
|
||||||
) or not evennia.EVENNIA_SERVICE.amp_protocol:
|
) or not evennia.EVENNIA_PORTAL_SERVICE.amp_protocol:
|
||||||
if not session or not self.connection_task:
|
if not session or not self.connection_task:
|
||||||
self.connection_task = reactor.callLater(
|
self.connection_task = reactor.callLater(
|
||||||
_MIN_TIME_BETWEEN_CONNECTS, self.connect, None
|
_MIN_TIME_BETWEEN_CONNECTS, self.connect, None
|
||||||
|
|
@ -156,7 +156,7 @@ class PortalSessionHandler(SessionHandler):
|
||||||
|
|
||||||
self[session.sessid] = session
|
self[session.sessid] = session
|
||||||
session.server_connected = True
|
session.server_connected = True
|
||||||
evennia.EVENNIA_SERVICE.amp_protocol.send_AdminPortal2Server(
|
evennia.EVENNIA_PORTAL_SERVICE.amp_protocol.send_AdminPortal2Server(
|
||||||
session, operation=PCONN, sessiondata=sessdata
|
session, operation=PCONN, sessiondata=sessdata
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -175,7 +175,7 @@ class PortalSessionHandler(SessionHandler):
|
||||||
# once to the server - if so we must re-sync woth the server, otherwise
|
# once to the server - if so we must re-sync woth the server, otherwise
|
||||||
# we skip this step.
|
# we skip this step.
|
||||||
sessdata = session.get_sync_data()
|
sessdata = session.get_sync_data()
|
||||||
if evennia.EVENNIA_SERVICE.amp_protocol:
|
if evennia.EVENNIA_PORTAL_SERVICE.amp_protocol:
|
||||||
# we only send sessdata that should not have changed
|
# we only send sessdata that should not have changed
|
||||||
# at the server level at this point
|
# at the server level at this point
|
||||||
sessdata = dict(
|
sessdata = dict(
|
||||||
|
|
@ -192,7 +192,7 @@ class PortalSessionHandler(SessionHandler):
|
||||||
"server_data",
|
"server_data",
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
evennia.EVENNIA_SERVICE.amp_protocol.send_AdminPortal2Server(
|
evennia.EVENNIA_PORTAL_SERVICE.amp_protocol.send_AdminPortal2Server(
|
||||||
session, operation=PCONNSYNC, sessiondata=sessdata
|
session, operation=PCONNSYNC, sessiondata=sessdata
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -222,13 +222,17 @@ class PortalSessionHandler(SessionHandler):
|
||||||
del self[session.sessid]
|
del self[session.sessid]
|
||||||
|
|
||||||
# Tell the Server to disconnect its version of the Session as well.
|
# Tell the Server to disconnect its version of the Session as well.
|
||||||
evennia.EVENNIA_SERVICE.amp_protocol.send_AdminPortal2Server(session, operation=PDISCONN)
|
evennia.EVENNIA_PORTAL_SERVICE.amp_protocol.send_AdminPortal2Server(
|
||||||
|
session, operation=PDISCONN
|
||||||
|
)
|
||||||
|
|
||||||
def disconnect_all(self):
|
def disconnect_all(self):
|
||||||
"""
|
"""
|
||||||
Disconnect all sessions, informing the Server.
|
Disconnect all sessions, informing the Server.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
if settings._TEST_ENVIRONMENT:
|
||||||
|
return
|
||||||
|
|
||||||
def _callback(result, sessionhandler):
|
def _callback(result, sessionhandler):
|
||||||
# we set a watchdog to stop self.disconnect from deleting
|
# we set a watchdog to stop self.disconnect from deleting
|
||||||
|
|
@ -240,7 +244,8 @@ class PortalSessionHandler(SessionHandler):
|
||||||
|
|
||||||
# inform Server; wait until finished sending before we continue
|
# inform Server; wait until finished sending before we continue
|
||||||
# removing all the sessions.
|
# removing all the sessions.
|
||||||
evennia.EVENNIA_SERVICE.amp_protocol.send_AdminPortal2Server(
|
|
||||||
|
evennia.EVENNIA_PORTAL_SERVICE.amp_protocol.send_AdminPortal2Server(
|
||||||
DUMMYSESSION, operation=PDISCONNALL
|
DUMMYSESSION, operation=PDISCONNALL
|
||||||
).addCallback(_callback, self)
|
).addCallback(_callback, self)
|
||||||
|
|
||||||
|
|
@ -434,7 +439,7 @@ class PortalSessionHandler(SessionHandler):
|
||||||
self.data_out(session, text=[[_ERROR_COMMAND_OVERFLOW], {}])
|
self.data_out(session, text=[[_ERROR_COMMAND_OVERFLOW], {}])
|
||||||
return
|
return
|
||||||
|
|
||||||
if not evennia.EVENNIA_SERVICE.amp_protocol:
|
if not evennia.EVENNIA_PORTAL_SERVICE.amp_protocol:
|
||||||
# this can happen if someone connects before AMP connection
|
# this can happen if someone connects before AMP connection
|
||||||
# was established (usually on first start)
|
# was established (usually on first start)
|
||||||
reactor.callLater(1.0, self.data_in, session, **kwargs)
|
reactor.callLater(1.0, self.data_in, session, **kwargs)
|
||||||
|
|
@ -445,7 +450,7 @@ class PortalSessionHandler(SessionHandler):
|
||||||
|
|
||||||
# relay data to Server
|
# relay data to Server
|
||||||
session.cmd_last = now
|
session.cmd_last = now
|
||||||
evennia.EVENNIA_SERVICE.amp_protocol.send_MsgPortal2Server(session, **kwargs)
|
evennia.EVENNIA_PORTAL_SERVICE.amp_protocol.send_MsgPortal2Server(session, **kwargs)
|
||||||
|
|
||||||
# eventual local echo (text input only)
|
# eventual local echo (text input only)
|
||||||
if "text" in kwargs and session.protocol_flags.get("LOCALECHO", False):
|
if "text" in kwargs and session.protocol_flags.get("LOCALECHO", False):
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,8 @@ from twisted.trial.unittest import TestCase as TwistedTestCase
|
||||||
import evennia
|
import evennia
|
||||||
from evennia.server.portal import irc
|
from evennia.server.portal import irc
|
||||||
from evennia.utils.test_resources import BaseEvenniaTest
|
from evennia.utils.test_resources import BaseEvenniaTest
|
||||||
|
from evennia.server.portal.service import EvenniaPortalService
|
||||||
|
from evennia.server.portal.portalsessionhandler import PortalSessionHandler
|
||||||
|
|
||||||
from .amp import (
|
from .amp import (
|
||||||
AMP_MAXLEN,
|
AMP_MAXLEN,
|
||||||
|
|
@ -221,8 +223,13 @@ class TestIRC(TestCase):
|
||||||
class TestTelnet(TwistedTestCase):
|
class TestTelnet(TwistedTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
|
self.portal = EvenniaPortalService()
|
||||||
|
evennia.EVENNIA_PORTAL_SERVICE = self.portal
|
||||||
|
self.amp_server_factory = AMPServerFactory(self.portal)
|
||||||
|
self.amp_server = self.amp_server_factory.buildProtocol("127.0.0.1")
|
||||||
factory = TelnetServerFactory()
|
factory = TelnetServerFactory()
|
||||||
factory.protocol = TelnetProtocol
|
factory.protocol = TelnetProtocol
|
||||||
|
evennia.PORTAL_SESSION_HANDLER = PortalSessionHandler()
|
||||||
factory.sessionhandler = evennia.PORTAL_SESSION_HANDLER
|
factory.sessionhandler = evennia.PORTAL_SESSION_HANDLER
|
||||||
factory.sessionhandler.portal = Mock()
|
factory.sessionhandler.portal = Mock()
|
||||||
self.proto = factory.buildProtocol(("localhost", 0))
|
self.proto = factory.buildProtocol(("localhost", 0))
|
||||||
|
|
@ -287,8 +294,13 @@ class TestTelnet(TwistedTestCase):
|
||||||
class TestWebSocket(BaseEvenniaTest):
|
class TestWebSocket(BaseEvenniaTest):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
|
self.portal = EvenniaPortalService()
|
||||||
|
evennia.EVENNIA_PORTAL_SERVICE = self.portal
|
||||||
|
self.amp_server_factory = AMPServerFactory(self.portal)
|
||||||
|
self.amp_server = self.amp_server_factory.buildProtocol("127.0.0.1")
|
||||||
self.proto = WebSocketClient()
|
self.proto = WebSocketClient()
|
||||||
self.proto.factory = WebSocketServerFactory()
|
self.proto.factory = WebSocketServerFactory()
|
||||||
|
evennia.PORTAL_SESSION_HANDLER = PortalSessionHandler()
|
||||||
self.proto.factory.sessionhandler = evennia.PORTAL_SESSION_HANDLER
|
self.proto.factory.sessionhandler = evennia.PORTAL_SESSION_HANDLER
|
||||||
self.proto.sessionhandler = evennia.PORTAL_SESSION_HANDLER
|
self.proto.sessionhandler = evennia.PORTAL_SESSION_HANDLER
|
||||||
self.proto.sessionhandler.portal = Mock()
|
self.proto.sessionhandler.portal = Mock()
|
||||||
|
|
|
||||||
|
|
@ -26,9 +26,7 @@ _SA = object.__setattr__
|
||||||
|
|
||||||
|
|
||||||
class EvenniaServerService(MultiService):
|
class EvenniaServerService(MultiService):
|
||||||
|
|
||||||
def _wrap_sigint_handler(self, *args):
|
def _wrap_sigint_handler(self, *args):
|
||||||
|
|
||||||
if hasattr(self, "web_root"):
|
if hasattr(self, "web_root"):
|
||||||
d = self.web_root.empty_threadpool()
|
d = self.web_root.empty_threadpool()
|
||||||
d.addCallback(lambda _: self.shutdown("reload", _reactor_stopping=True))
|
d.addCallback(lambda _: self.shutdown("reload", _reactor_stopping=True))
|
||||||
|
|
@ -41,6 +39,7 @@ class EvenniaServerService(MultiService):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.maintenance_count = 0
|
self.maintenance_count = 0
|
||||||
self.amp_protocol = None # set by amp factory
|
self.amp_protocol = None # set by amp factory
|
||||||
|
self.amp_service = None
|
||||||
self.info_dict = {
|
self.info_dict = {
|
||||||
"servername": settings.SERVERNAME,
|
"servername": settings.SERVERNAME,
|
||||||
"version": get_evennia_version(),
|
"version": get_evennia_version(),
|
||||||
|
|
@ -72,8 +71,6 @@ class EvenniaServerService(MultiService):
|
||||||
if isinstance(mod, str)
|
if isinstance(mod, str)
|
||||||
]
|
]
|
||||||
|
|
||||||
# Server startup methods
|
|
||||||
|
|
||||||
def server_maintenance(self):
|
def server_maintenance(self):
|
||||||
"""
|
"""
|
||||||
This maintenance function handles repeated checks and updates that
|
This maintenance function handles repeated checks and updates that
|
||||||
|
|
@ -81,6 +78,7 @@ class EvenniaServerService(MultiService):
|
||||||
"""
|
"""
|
||||||
if not self._flush_cache:
|
if not self._flush_cache:
|
||||||
from evennia.utils.idmapper.models import conditional_flush as _FLUSH_CACHE
|
from evennia.utils.idmapper.models import conditional_flush as _FLUSH_CACHE
|
||||||
|
|
||||||
self._flush_cache = _FLUSH_CACHE
|
self._flush_cache = _FLUSH_CACHE
|
||||||
|
|
||||||
self.maintenance_count += 1
|
self.maintenance_count += 1
|
||||||
|
|
@ -89,7 +87,9 @@ class EvenniaServerService(MultiService):
|
||||||
if self.maintenance_count == 1:
|
if self.maintenance_count == 1:
|
||||||
# first call after a reload
|
# first call after a reload
|
||||||
evennia.gametime.SERVER_START_TIME = now
|
evennia.gametime.SERVER_START_TIME = now
|
||||||
evennia.gametime.SERVER_RUNTIME = evennia.ServerConfig.objects.conf("runtime", default=0.0)
|
evennia.gametime.SERVER_RUNTIME = evennia.ServerConfig.objects.conf(
|
||||||
|
"runtime", default=0.0
|
||||||
|
)
|
||||||
_LAST_SERVER_TIME_SNAPSHOT = now
|
_LAST_SERVER_TIME_SNAPSHOT = now
|
||||||
else:
|
else:
|
||||||
# adjust the runtime not with 60s but with the actual elapsed time
|
# adjust the runtime not with 60s but with the actual elapsed time
|
||||||
|
|
@ -109,20 +109,7 @@ class EvenniaServerService(MultiService):
|
||||||
# (see https://github.com/evennia/evennia/issues/1376)
|
# (see https://github.com/evennia/evennia/issues/1376)
|
||||||
connection.close()
|
connection.close()
|
||||||
|
|
||||||
# handle idle timeouts
|
self.process_idle_timeouts()
|
||||||
if settings.IDLE_TIMEOUT > 0:
|
|
||||||
reason = _("idle timeout exceeded")
|
|
||||||
to_disconnect = []
|
|
||||||
for session in (
|
|
||||||
sess for sess in evennia.SESSION_HANDLER.values() if (now - sess.cmd_last) > settings.IDLE_TIMEOUT
|
|
||||||
):
|
|
||||||
if not session.account or not session.account.access(
|
|
||||||
session.account, "noidletimeout", default=False
|
|
||||||
):
|
|
||||||
to_disconnect.append(session)
|
|
||||||
|
|
||||||
for session in to_disconnect:
|
|
||||||
evennia.SESSION_HANDLER.disconnect(session, reason=reason)
|
|
||||||
|
|
||||||
# run unpuppet hooks for objects that are marked as being puppeted,
|
# run unpuppet hooks for objects that are marked as being puppeted,
|
||||||
# but which lacks an account (indicates a broken unpuppet operation
|
# but which lacks an account (indicates a broken unpuppet operation
|
||||||
|
|
@ -138,6 +125,26 @@ class EvenniaServerService(MultiService):
|
||||||
if unpuppet_count:
|
if unpuppet_count:
|
||||||
logger.log_msg(f"Ran unpuppet-hooks for {unpuppet_count} link-dead puppets.")
|
logger.log_msg(f"Ran unpuppet-hooks for {unpuppet_count} link-dead puppets.")
|
||||||
|
|
||||||
|
def process_idle_timeouts(self):
|
||||||
|
# handle idle timeouts
|
||||||
|
if settings.IDLE_TIMEOUT > 0:
|
||||||
|
now = time.time()
|
||||||
|
reason = _("idle timeout exceeded")
|
||||||
|
to_disconnect = []
|
||||||
|
for session in (
|
||||||
|
sess
|
||||||
|
for sess in evennia.SESSION_HANDLER.values()
|
||||||
|
if (now - sess.cmd_last) > settings.IDLE_TIMEOUT
|
||||||
|
):
|
||||||
|
if not session.account or not session.account.access(
|
||||||
|
session.account, "noidletimeout", default=False
|
||||||
|
):
|
||||||
|
to_disconnect.append(session)
|
||||||
|
|
||||||
|
for session in to_disconnect:
|
||||||
|
evennia.SESSION_HANDLER.disconnect(session, reason=reason)
|
||||||
|
|
||||||
|
# Server startup methods
|
||||||
def privilegedStartService(self):
|
def privilegedStartService(self):
|
||||||
self.start_time = time.time()
|
self.start_time = time.time()
|
||||||
|
|
||||||
|
|
@ -209,9 +216,9 @@ class EvenniaServerService(MultiService):
|
||||||
from evennia.server import amp_client
|
from evennia.server import amp_client
|
||||||
|
|
||||||
factory = amp_client.AMPClientFactory(self)
|
factory = amp_client.AMPClientFactory(self)
|
||||||
amp_service = internet.TCPClient(settings.AMP_HOST, settings.AMP_PORT, factory)
|
self.amp_service = internet.TCPClient(settings.AMP_HOST, settings.AMP_PORT, factory)
|
||||||
amp_service.setName("ServerAMPClient")
|
self.amp_service.setName("ServerAMPClient")
|
||||||
amp_service.setServiceParent(self)
|
self.amp_service.setServiceParent(self)
|
||||||
|
|
||||||
def register_webserver(self):
|
def register_webserver(self):
|
||||||
# Start a django-compatible webserver.
|
# Start a django-compatible webserver.
|
||||||
|
|
@ -292,7 +299,6 @@ class EvenniaServerService(MultiService):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
# setting names
|
# setting names
|
||||||
settings_names = (
|
settings_names = (
|
||||||
"CMDSET_CHARACTER",
|
"CMDSET_CHARACTER",
|
||||||
|
|
@ -401,6 +407,7 @@ class EvenniaServerService(MultiService):
|
||||||
except Exception:
|
except Exception:
|
||||||
# stop server if this happens.
|
# stop server if this happens.
|
||||||
print(traceback.format_exc())
|
print(traceback.format_exc())
|
||||||
|
if not settings._TEST_ENVIRONMENT or not evennia.SESSION_HANDLER:
|
||||||
print("Error in initial setup. Stopping Server + Portal.")
|
print("Error in initial setup. Stopping Server + Portal.")
|
||||||
evennia.SESSION_HANDLER.portal_shutdown()
|
evennia.SESSION_HANDLER.portal_shutdown()
|
||||||
|
|
||||||
|
|
@ -523,7 +530,10 @@ class EvenniaServerService(MultiService):
|
||||||
if self.amp_protocol:
|
if self.amp_protocol:
|
||||||
yield evennia.SESSION_HANDLER.all_sessions_portal_sync()
|
yield evennia.SESSION_HANDLER.all_sessions_portal_sync()
|
||||||
else: # shutdown
|
else: # shutdown
|
||||||
yield [_SA(p, "is_connected", False) for p in evennia.AccountDB.get_all_cached_instances()]
|
yield [
|
||||||
|
_SA(p, "is_connected", False)
|
||||||
|
for p in evennia.AccountDB.get_all_cached_instances()
|
||||||
|
]
|
||||||
yield [o.at_server_shutdown() for o in evennia.ObjectDB.get_all_cached_instances()]
|
yield [o.at_server_shutdown() for o in evennia.ObjectDB.get_all_cached_instances()]
|
||||||
yield [
|
yield [
|
||||||
(p.unpuppet_all(), p.at_server_shutdown())
|
(p.unpuppet_all(), p.at_server_shutdown())
|
||||||
|
|
@ -575,7 +585,7 @@ class EvenniaServerService(MultiService):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
for mod in self.start_stop_modules:
|
for mod in self.start_stop_modules:
|
||||||
if (hook := getattr(mod, hookname, None)):
|
if hook := getattr(mod, hookname, None):
|
||||||
hook()
|
hook()
|
||||||
|
|
||||||
def at_server_init(self):
|
def at_server_init(self):
|
||||||
|
|
|
||||||
|
|
@ -307,7 +307,7 @@ class ServerSessionHandler(SessionHandler):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
evennia.EVENNIA_SERVICE_data = {"servername": _SERVERNAME}
|
evennia.server_data = {"servername": _SERVERNAME}
|
||||||
# will be set on psync
|
# will be set on psync
|
||||||
self.portal_start_time = 0.0
|
self.portal_start_time = 0.0
|
||||||
|
|
||||||
|
|
@ -411,7 +411,7 @@ class ServerSessionHandler(SessionHandler):
|
||||||
mode = "reload"
|
mode = "reload"
|
||||||
|
|
||||||
# tell the server hook we synced
|
# tell the server hook we synced
|
||||||
evennia.EVENNIA_SERVICE.at_post_portal_sync(mode)
|
evennia.EVENNIA_SERVER_SERVICE.at_post_portal_sync(mode)
|
||||||
# announce the reconnection
|
# announce the reconnection
|
||||||
if _BROADCAST_SERVER_RESTART_MESSAGES:
|
if _BROADCAST_SERVER_RESTART_MESSAGES:
|
||||||
self.announce_all(_(" ... Server restarted."))
|
self.announce_all(_(" ... Server restarted."))
|
||||||
|
|
@ -467,7 +467,7 @@ class ServerSessionHandler(SessionHandler):
|
||||||
the Server.
|
the Server.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
evennia.EVENNIA_SERVICE.amp_protocol.send_AdminServer2Portal(
|
evennia.EVENNIA_SERVER_SERVICE.amp_protocol.send_AdminServer2Portal(
|
||||||
DUMMYSESSION, operation=amp.SCONN, protocol_path=protocol_path, config=configdict
|
DUMMYSESSION, operation=amp.SCONN, protocol_path=protocol_path, config=configdict
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -476,14 +476,18 @@ class ServerSessionHandler(SessionHandler):
|
||||||
Called by server when reloading. We tell the portal to start a new server instance.
|
Called by server when reloading. We tell the portal to start a new server instance.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
evennia.EVENNIA_SERVICE.amp_protocol.send_AdminServer2Portal(DUMMYSESSION, operation=amp.SRELOAD)
|
evennia.EVENNIA_SERVER_SERVICE.amp_protocol.send_AdminServer2Portal(
|
||||||
|
DUMMYSESSION, operation=amp.SRELOAD
|
||||||
|
)
|
||||||
|
|
||||||
def portal_reset_server(self):
|
def portal_reset_server(self):
|
||||||
"""
|
"""
|
||||||
Called by server when reloading. We tell the portal to start a new server instance.
|
Called by server when reloading. We tell the portal to start a new server instance.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
evennia.EVENNIA_SERVICE.amp_protocol.send_AdminServer2Portal(DUMMYSESSION, operation=amp.SRESET)
|
evennia.EVENNIA_SERVER_SERVICE.amp_protocol.send_AdminServer2Portal(
|
||||||
|
DUMMYSESSION, operation=amp.SRESET
|
||||||
|
)
|
||||||
|
|
||||||
def portal_shutdown(self):
|
def portal_shutdown(self):
|
||||||
"""
|
"""
|
||||||
|
|
@ -491,7 +495,9 @@ class ServerSessionHandler(SessionHandler):
|
||||||
itself down)
|
itself down)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
evennia.EVENNIA_SERVICE.amp_protocol.send_AdminServer2Portal(DUMMYSESSION, operation=amp.PSHUTD)
|
evennia.EVENNIA_SERVER_SERVICE.amp_protocol.send_AdminServer2Portal(
|
||||||
|
DUMMYSESSION, operation=amp.PSHUTD
|
||||||
|
)
|
||||||
|
|
||||||
def login(self, session, account, force=False, testmode=False):
|
def login(self, session, account, force=False, testmode=False):
|
||||||
"""
|
"""
|
||||||
|
|
@ -537,7 +543,7 @@ class ServerSessionHandler(SessionHandler):
|
||||||
session.logged_in = True
|
session.logged_in = True
|
||||||
# sync the portal to the session
|
# sync the portal to the session
|
||||||
if not testmode:
|
if not testmode:
|
||||||
evennia.EVENNIA_SERVICE.amp_protocol.send_AdminServer2Portal(
|
evennia.EVENNIA_SERVER_SERVICE.amp_protocol.send_AdminServer2Portal(
|
||||||
session, operation=amp.SLOGIN, sessiondata={"logged_in": True, "uid": session.uid}
|
session, operation=amp.SLOGIN, sessiondata={"logged_in": True, "uid": session.uid}
|
||||||
)
|
)
|
||||||
account.at_post_login(session=session)
|
account.at_post_login(session=session)
|
||||||
|
|
@ -582,7 +588,7 @@ class ServerSessionHandler(SessionHandler):
|
||||||
del self[sessid]
|
del self[sessid]
|
||||||
if sync_portal:
|
if sync_portal:
|
||||||
# inform portal that session should be closed.
|
# inform portal that session should be closed.
|
||||||
evennia.EVENNIA_SERVICE.amp_protocol.send_AdminServer2Portal(
|
evennia.EVENNIA_SERVER_SERVICE.amp_protocol.send_AdminServer2Portal(
|
||||||
session, operation=amp.SDISCONN, reason=reason
|
session, operation=amp.SDISCONN, reason=reason
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -593,7 +599,7 @@ class ServerSessionHandler(SessionHandler):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
sessdata = self.get_all_sync_data()
|
sessdata = self.get_all_sync_data()
|
||||||
return evennia.EVENNIA_SERVICE.amp_protocol.send_AdminServer2Portal(
|
return evennia.EVENNIA_SERVER_SERVICE.amp_protocol.send_AdminServer2Portal(
|
||||||
DUMMYSESSION, operation=amp.SSYNC, sessiondata=sessdata
|
DUMMYSESSION, operation=amp.SSYNC, sessiondata=sessdata
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -604,7 +610,7 @@ class ServerSessionHandler(SessionHandler):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
sessdata = {session.sessid: session.get_sync_data()}
|
sessdata = {session.sessid: session.get_sync_data()}
|
||||||
return evennia.EVENNIA_SERVICE.amp_protocol.send_AdminServer2Portal(
|
return evennia.EVENNIA_SERVER_SERVICE.amp_protocol.send_AdminServer2Portal(
|
||||||
DUMMYSESSION, operation=amp.SSYNC, sessiondata=sessdata, clean=False
|
DUMMYSESSION, operation=amp.SSYNC, sessiondata=sessdata, clean=False
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -617,7 +623,7 @@ class ServerSessionHandler(SessionHandler):
|
||||||
more sessions in detail.
|
more sessions in detail.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return evennia.EVENNIA_SERVICE.amp_protocol.send_AdminServer2Portal(
|
return evennia.EVENNIA_SERVER_SERVICE.amp_protocol.send_AdminServer2Portal(
|
||||||
DUMMYSESSION, operation=amp.SSYNC, sessiondata=session_data, clean=False
|
DUMMYSESSION, operation=amp.SSYNC, sessiondata=session_data, clean=False
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -633,7 +639,7 @@ class ServerSessionHandler(SessionHandler):
|
||||||
for session in self:
|
for session in self:
|
||||||
del session
|
del session
|
||||||
# tell portal to disconnect all sessions
|
# tell portal to disconnect all sessions
|
||||||
evennia.EVENNIA_SERVICE.amp_protocol.send_AdminServer2Portal(
|
evennia.EVENNIA_SERVER_SERVICE.amp_protocol.send_AdminServer2Portal(
|
||||||
DUMMYSESSION, operation=amp.SDISCONNALL, reason=reason
|
DUMMYSESSION, operation=amp.SDISCONNALL, reason=reason
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -817,7 +823,7 @@ class ServerSessionHandler(SessionHandler):
|
||||||
kwargs = self.clean_senddata(session, kwargs)
|
kwargs = self.clean_senddata(session, kwargs)
|
||||||
|
|
||||||
# send across AMP
|
# send across AMP
|
||||||
evennia.EVENNIA_SERVICE.amp_protocol.send_MsgServer2Portal(session, **kwargs)
|
evennia.EVENNIA_SERVER_SERVICE.amp_protocol.send_MsgServer2Portal(session, **kwargs)
|
||||||
|
|
||||||
def get_inputfuncs(self):
|
def get_inputfuncs(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ class _TestAMP(TwistedTestCase):
|
||||||
return all_sent
|
return all_sent
|
||||||
|
|
||||||
|
|
||||||
@patch("evennia.server.server.LoopingCall", MagicMock())
|
@patch("evennia.server.service.LoopingCall", MagicMock())
|
||||||
@patch("evennia.server.portal.amp.amp.BinaryBoxProtocol.transport")
|
@patch("evennia.server.portal.amp.amp.BinaryBoxProtocol.transport")
|
||||||
class TestAMPClientSend(_TestAMP):
|
class TestAMPClientSend(_TestAMP):
|
||||||
"""Test amp client sending data"""
|
"""Test amp client sending data"""
|
||||||
|
|
@ -90,7 +90,9 @@ class TestAMPClientSend(_TestAMP):
|
||||||
|
|
||||||
self._connect_server(mocktransport)
|
self._connect_server(mocktransport)
|
||||||
self.amp_server.dataReceived(wire_data)
|
self.amp_server.dataReceived(wire_data)
|
||||||
self.portal.sessions.data_out.assert_called_with(self.portalsession, text={"foo": "bar"})
|
evennia.PORTAL_SESSION_HANDLER.data_out.assert_called_with(
|
||||||
|
self.portalsession, text={"foo": "bar"}
|
||||||
|
)
|
||||||
|
|
||||||
def test_adminserver2portal(self, mocktransport):
|
def test_adminserver2portal(self, mocktransport):
|
||||||
self._connect_client(mocktransport)
|
self._connect_client(mocktransport)
|
||||||
|
|
@ -117,7 +119,7 @@ class TestAMPClientRecv(_TestAMP):
|
||||||
|
|
||||||
self._connect_client(mocktransport)
|
self._connect_client(mocktransport)
|
||||||
self.amp_client.dataReceived(wire_data)
|
self.amp_client.dataReceived(wire_data)
|
||||||
self.server.sessions.data_in.assert_called_with(self.session, text={"foo": "bar"})
|
evennia.SERVER_SESSION_HANDLER.data_in.assert_called_with(self.session, text={"foo": "bar"})
|
||||||
|
|
||||||
def test_adminportal2server(self, mocktransport):
|
def test_adminportal2server(self, mocktransport):
|
||||||
self._connect_server(mocktransport)
|
self._connect_server(mocktransport)
|
||||||
|
|
@ -126,6 +128,6 @@ class TestAMPClientRecv(_TestAMP):
|
||||||
wire_data = self._catch_wire_read(mocktransport)[0]
|
wire_data = self._catch_wire_read(mocktransport)[0]
|
||||||
|
|
||||||
self._connect_client(mocktransport)
|
self._connect_client(mocktransport)
|
||||||
self.server.sessions.portal_disconnect_all = MagicMock()
|
evennia.SERVER_SESSION_HANDLER.portal_disconnect_all = MagicMock()
|
||||||
self.amp_client.dataReceived(wire_data)
|
self.amp_client.dataReceived(wire_data)
|
||||||
self.server.sessions.portal_disconnect_all.assert_called()
|
evennia.SERVER_SESSION_HANDLER.portal_disconnect_all.assert_called()
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,14 @@
|
||||||
Test the main server component
|
Test the main server component
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
import evennia
|
||||||
from unittest import TestCase
|
from unittest import TestCase
|
||||||
|
|
||||||
from django.test import override_settings
|
from django.test import override_settings
|
||||||
from mock import DEFAULT, MagicMock, call, patch
|
from mock import DEFAULT, MagicMock, call, patch
|
||||||
|
|
||||||
|
|
||||||
@patch("evennia.server.server.LoopingCall", new=MagicMock())
|
@patch("evennia.server.service.LoopingCall", new=MagicMock())
|
||||||
class TestServer(TestCase):
|
class TestServer(TestCase):
|
||||||
"""
|
"""
|
||||||
Test server module.
|
Test server module.
|
||||||
|
|
@ -17,78 +17,76 @@ class TestServer(TestCase):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
# Running this first line ensures that the EVENNIA_SERVICE is instantiated.
|
||||||
from evennia.server import server
|
from evennia.server import server
|
||||||
|
|
||||||
self.server = server
|
self.server = evennia.EVENNIA_SERVER_SERVICE
|
||||||
|
|
||||||
|
@override_settings(IDMAPPER_CACHE_MAXSIZE=1000)
|
||||||
def test__server_maintenance_reset(self):
|
def test__server_maintenance_reset(self):
|
||||||
with patch.multiple(
|
with patch.object(self.server, "_flush_cache", new=MagicMock()) as mockflush, patch.object(
|
||||||
"evennia.server.server",
|
evennia, "ServerConfig", new=MagicMock()
|
||||||
|
) as mockconf, patch.multiple(
|
||||||
|
"evennia.server.service",
|
||||||
LoopingCall=DEFAULT,
|
LoopingCall=DEFAULT,
|
||||||
Evennia=DEFAULT,
|
|
||||||
_FLUSH_CACHE=DEFAULT,
|
|
||||||
connection=DEFAULT,
|
connection=DEFAULT,
|
||||||
_IDMAPPER_CACHE_MAXSIZE=1000,
|
|
||||||
_MAINTENANCE_COUNT=0,
|
|
||||||
ServerConfig=DEFAULT,
|
|
||||||
) as mocks:
|
) as mocks:
|
||||||
|
self.server.maintenance_count = 0
|
||||||
|
|
||||||
mocks["connection"].close = MagicMock()
|
mocks["connection"].close = MagicMock()
|
||||||
mocks["ServerConfig"].objects.conf = MagicMock(return_value=456)
|
mockconf.objects.conf = MagicMock(return_value=456)
|
||||||
|
|
||||||
# flush cache
|
# flush cache
|
||||||
self.server._server_maintenance()
|
self.server.server_maintenance()
|
||||||
mocks["ServerConfig"].objects.conf.assert_called_with("runtime", 456)
|
mockconf.objects.conf.assert_called_with("runtime", 456)
|
||||||
|
|
||||||
|
@override_settings(IDMAPPER_CACHE_MAXSIZE=1000)
|
||||||
def test__server_maintenance_flush(self):
|
def test__server_maintenance_flush(self):
|
||||||
with patch.multiple(
|
with patch.multiple(
|
||||||
"evennia.server.server",
|
"evennia.server.service",
|
||||||
LoopingCall=DEFAULT,
|
LoopingCall=DEFAULT,
|
||||||
Evennia=DEFAULT,
|
|
||||||
_FLUSH_CACHE=DEFAULT,
|
|
||||||
connection=DEFAULT,
|
connection=DEFAULT,
|
||||||
_IDMAPPER_CACHE_MAXSIZE=1000,
|
) as mocks, patch.object(
|
||||||
_MAINTENANCE_COUNT=5 - 1,
|
evennia, "ServerConfig", new=MagicMock()
|
||||||
ServerConfig=DEFAULT,
|
) as mockconf, patch.object(
|
||||||
) as mocks:
|
self.server, "_flush_cache", new=MagicMock()
|
||||||
|
) as mockflush:
|
||||||
mocks["connection"].close = MagicMock()
|
mocks["connection"].close = MagicMock()
|
||||||
mocks["ServerConfig"].objects.conf = MagicMock(return_value=100)
|
mockconf.objects.conf = MagicMock(return_value=100)
|
||||||
|
self.server.maintenance_count = 5 - 1
|
||||||
# flush cache
|
# flush cache
|
||||||
self.server._server_maintenance()
|
self.server.server_maintenance()
|
||||||
mocks["_FLUSH_CACHE"].assert_called_with(1000)
|
self.server._flush_cache.assert_called_with(1000)
|
||||||
|
|
||||||
|
@override_settings(IDMAPPER_CACHE_MAXSIZE=1000)
|
||||||
def test__server_maintenance_close_connection(self):
|
def test__server_maintenance_close_connection(self):
|
||||||
with patch.multiple(
|
with patch.multiple(
|
||||||
"evennia.server.server",
|
"evennia.server.service",
|
||||||
LoopingCall=DEFAULT,
|
LoopingCall=DEFAULT,
|
||||||
Evennia=DEFAULT,
|
|
||||||
_FLUSH_CACHE=DEFAULT,
|
|
||||||
connection=DEFAULT,
|
connection=DEFAULT,
|
||||||
_IDMAPPER_CACHE_MAXSIZE=1000,
|
) as mocks, patch.object(evennia, "ServerConfig", new=MagicMock()) as mockconf:
|
||||||
_MAINTENANCE_COUNT=(60 * 7) - 1,
|
self.server._flush_cache = MagicMock()
|
||||||
_LAST_SERVER_TIME_SNAPSHOT=0,
|
self.server.maintenance_count = (60 * 7) - 1
|
||||||
ServerConfig=DEFAULT,
|
self.server._last_server_time_snapshot = 0
|
||||||
) as mocks:
|
|
||||||
mocks["connection"].close = MagicMock()
|
mocks["connection"].close = MagicMock()
|
||||||
mocks["ServerConfig"].objects.conf = MagicMock(return_value=100)
|
mockconf.objects.conf = MagicMock(return_value=100)
|
||||||
self.server._server_maintenance()
|
self.server.server_maintenance()
|
||||||
mocks["connection"].close.assert_called()
|
mocks["connection"].close.assert_called()
|
||||||
|
|
||||||
|
@override_settings(IDLE_TIMEOUT=10)
|
||||||
def test__server_maintenance_idle_time(self):
|
def test__server_maintenance_idle_time(self):
|
||||||
with patch.multiple(
|
with patch.multiple(
|
||||||
"evennia.server.server",
|
"evennia.server.service",
|
||||||
LoopingCall=DEFAULT,
|
LoopingCall=DEFAULT,
|
||||||
Evennia=DEFAULT,
|
|
||||||
_FLUSH_CACHE=DEFAULT,
|
|
||||||
connection=DEFAULT,
|
connection=DEFAULT,
|
||||||
_IDMAPPER_CACHE_MAXSIZE=1000,
|
|
||||||
_MAINTENANCE_COUNT=(3600 * 7) - 1,
|
|
||||||
_LAST_SERVER_TIME_SNAPSHOT=0,
|
|
||||||
SESSIONS=DEFAULT,
|
|
||||||
_IDLE_TIMEOUT=10,
|
|
||||||
time=DEFAULT,
|
time=DEFAULT,
|
||||||
ServerConfig=DEFAULT,
|
) as mocks, patch.object(
|
||||||
) as mocks:
|
evennia, "ServerConfig", new=MagicMock()
|
||||||
|
) as mockconf, patch.object(
|
||||||
|
evennia, "SESSION_HANDLER", new=MagicMock()
|
||||||
|
) as mocksess:
|
||||||
|
self.server.maintenance_count = (3600 * 7) - 1
|
||||||
|
self.server._last_server_time_snapshot = 0
|
||||||
sess1 = MagicMock()
|
sess1 = MagicMock()
|
||||||
sess2 = MagicMock()
|
sess2 = MagicMock()
|
||||||
sess3 = MagicMock()
|
sess3 = MagicMock()
|
||||||
|
|
@ -105,31 +103,25 @@ class TestServer(TestCase):
|
||||||
|
|
||||||
mocks["time"].time = MagicMock(return_value=1000)
|
mocks["time"].time = MagicMock(return_value=1000)
|
||||||
|
|
||||||
mocks["ServerConfig"].objects.conf = MagicMock(return_value=100)
|
mockconf.objects.conf = MagicMock(return_value=100)
|
||||||
mocks["SESSIONS"].values = MagicMock(return_value=[sess1, sess2, sess3, sess4])
|
mocksess.values = MagicMock(return_value=[sess1, sess2, sess3, sess4])
|
||||||
mocks["SESSIONS"].disconnect = MagicMock()
|
mocksess.disconnect = MagicMock()
|
||||||
|
|
||||||
self.server._server_maintenance()
|
self.server.server_maintenance()
|
||||||
reason = "idle timeout exceeded"
|
reason = "idle timeout exceeded"
|
||||||
calls = [call(sess1, reason=reason), call(sess4, reason=reason)]
|
calls = [call(sess1, reason=reason), call(sess4, reason=reason)]
|
||||||
mocks["SESSIONS"].disconnect.assert_has_calls(calls, any_order=True)
|
mocksess.disconnect.assert_has_calls(calls, any_order=True)
|
||||||
|
|
||||||
def test_evennia_start(self):
|
def test_update_defaults(self):
|
||||||
with patch.multiple("evennia.server.server", time=DEFAULT, service=DEFAULT) as mocks:
|
with patch.object(evennia, "ObjectDB", new=MagicMock()) as mockobj, patch.object(
|
||||||
mocks["time"].time = MagicMock(return_value=1000)
|
evennia, "AccountDB", new=MagicMock()
|
||||||
evennia = self.server.Evennia(MagicMock())
|
) as mockacc, patch.object(evennia, "ScriptDB", new=MagicMock()) as mockscr, patch.object(
|
||||||
self.assertEqual(evennia.start_time, 1000)
|
evennia, "ChannelDB", new=MagicMock()
|
||||||
|
) as mockchan, patch.object(
|
||||||
@patch("evennia.objects.models.ObjectDB")
|
evennia, "ServerConfig", new=MagicMock()
|
||||||
@patch("evennia.server.server.AccountDB")
|
) as mockconf:
|
||||||
@patch("evennia.server.server.ScriptDB")
|
for m in (mockscr, mockobj, mockacc, mockchan):
|
||||||
@patch("evennia.comms.models.ChannelDB")
|
m.objects.filter = MagicMock()
|
||||||
def test_update_defaults(self, mockchan, mockscript, mockacct, mockobj):
|
|
||||||
with patch.multiple("evennia.server.server", ServerConfig=DEFAULT) as mocks:
|
|
||||||
mockchan.objects.filter = MagicMock()
|
|
||||||
mockscript.objects.filter = MagicMock()
|
|
||||||
mockacct.objects.filter = MagicMock()
|
|
||||||
mockobj.objects.filter = MagicMock()
|
|
||||||
|
|
||||||
# fake mismatches
|
# fake mismatches
|
||||||
settings_names = (
|
settings_names = (
|
||||||
|
|
@ -148,16 +140,14 @@ class TestServer(TestCase):
|
||||||
def _mock_conf(key, *args):
|
def _mock_conf(key, *args):
|
||||||
return fakes[key]
|
return fakes[key]
|
||||||
|
|
||||||
mocks["ServerConfig"].objects.conf = _mock_conf
|
mockconf.objects.conf = _mock_conf
|
||||||
|
|
||||||
evennia = self.server.Evennia(MagicMock())
|
self.server.update_defaults()
|
||||||
evennia.update_defaults()
|
|
||||||
|
|
||||||
mockchan.objects.filter.assert_called()
|
for m in (mockscr, mockobj, mockacc, mockchan):
|
||||||
mockscript.objects.filter.assert_called()
|
m.objects.filter.assert_called()
|
||||||
mockacct.objects.filter.assert_called()
|
|
||||||
mockobj.objects.filter.assert_called()
|
|
||||||
|
|
||||||
|
@override_settings(_TEST_ENVIRONMENT=True)
|
||||||
def test_initial_setup(self):
|
def test_initial_setup(self):
|
||||||
from evennia.utils.create import create_account
|
from evennia.utils.create import create_account
|
||||||
|
|
||||||
|
|
@ -167,10 +157,10 @@ class TestServer(TestCase):
|
||||||
"evennia.server.initial_setup", reset_server=DEFAULT, AccountDB=DEFAULT
|
"evennia.server.initial_setup", reset_server=DEFAULT, AccountDB=DEFAULT
|
||||||
) as mocks:
|
) as mocks:
|
||||||
mocks["AccountDB"].objects.get = MagicMock(return_value=acct)
|
mocks["AccountDB"].objects.get = MagicMock(return_value=acct)
|
||||||
evennia = self.server.Evennia(MagicMock())
|
self.server.run_initial_setup()
|
||||||
evennia.run_initial_setup()
|
|
||||||
acct.delete()
|
acct.delete()
|
||||||
|
|
||||||
|
@override_settings(_TEST_ENVIRONMENT=True)
|
||||||
def test_initial_setup_retry(self):
|
def test_initial_setup_retry(self):
|
||||||
from evennia.utils.create import create_account
|
from evennia.utils.create import create_account
|
||||||
|
|
||||||
|
|
@ -185,14 +175,12 @@ class TestServer(TestCase):
|
||||||
mocks["AccountDB"].objects.get = MagicMock(return_value=acct)
|
mocks["AccountDB"].objects.get = MagicMock(return_value=acct)
|
||||||
# a last_initial_setup_step > 0
|
# a last_initial_setup_step > 0
|
||||||
mocks["ServerConfig"].objects.conf = MagicMock(return_value=4)
|
mocks["ServerConfig"].objects.conf = MagicMock(return_value=4)
|
||||||
evennia = self.server.Evennia(MagicMock())
|
self.server.run_initial_setup()
|
||||||
evennia.run_initial_setup()
|
|
||||||
acct.delete()
|
acct.delete()
|
||||||
|
|
||||||
@patch("evennia.server.server.INFO_DICT", {"test": "foo"})
|
|
||||||
def test_get_info_dict(self):
|
def test_get_info_dict(self):
|
||||||
evennia = self.server.Evennia(MagicMock())
|
with patch.object(self.server, "get_info_dict", return_value={"test": "foo"}) as mocks:
|
||||||
self.assertEqual(evennia.get_info_dict(), {"test": "foo"})
|
self.assertEqual(self.server.get_info_dict(), {"test": "foo"})
|
||||||
|
|
||||||
|
|
||||||
class TestInitHooks(TestCase):
|
class TestInitHooks(TestCase):
|
||||||
|
|
@ -200,7 +188,7 @@ class TestInitHooks(TestCase):
|
||||||
from evennia.server import server
|
from evennia.server import server
|
||||||
from evennia.utils import create
|
from evennia.utils import create
|
||||||
|
|
||||||
self.server = server
|
self.server = evennia.EVENNIA_SERVER_SERVICE
|
||||||
|
|
||||||
self.obj1 = create.object(key="HookTestObj1")
|
self.obj1 = create.object(key="HookTestObj1")
|
||||||
self.obj2 = create.object(key="HookTestObj2")
|
self.obj2 = create.object(key="HookTestObj2")
|
||||||
|
|
@ -211,44 +199,35 @@ class TestInitHooks(TestCase):
|
||||||
self.script1 = create.script(key="script1")
|
self.script1 = create.script(key="script1")
|
||||||
self.script2 = create.script(key="script2")
|
self.script2 = create.script(key="script2")
|
||||||
|
|
||||||
self.obj1.at_init = MagicMock()
|
self.objects = [
|
||||||
self.obj2.at_init = MagicMock()
|
self.obj1,
|
||||||
self.acct1.at_init = MagicMock()
|
self.obj2,
|
||||||
self.acct2.at_init = MagicMock()
|
self.acct1,
|
||||||
self.chan1.at_init = MagicMock()
|
self.acct2,
|
||||||
self.chan2.at_init = MagicMock()
|
self.chan1,
|
||||||
self.script1.at_init = MagicMock()
|
self.chan2,
|
||||||
self.script2.at_init = MagicMock()
|
self.script1,
|
||||||
|
self.script2,
|
||||||
|
]
|
||||||
|
|
||||||
|
for obj in self.objects:
|
||||||
|
obj.at_init = MagicMock()
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
self.obj1.delete()
|
for obj in self.objects:
|
||||||
self.obj2.delete()
|
obj.delete()
|
||||||
self.acct1.delete()
|
|
||||||
self.acct2.delete()
|
|
||||||
self.chan1.delete()
|
|
||||||
self.chan2.delete()
|
|
||||||
self.script1.delete()
|
|
||||||
self.script2.delete()
|
|
||||||
|
|
||||||
@override_settings(_TEST_ENVIRONMENT=True)
|
@override_settings(_TEST_ENVIRONMENT=True)
|
||||||
def test_run_init_hooks(self):
|
def test_run_init_hooks(self):
|
||||||
evennia = self.server.Evennia(MagicMock())
|
with patch.object(
|
||||||
|
self.server, "at_server_reload_start", new=MagicMock()
|
||||||
|
) as reload, patch.object(self.server, "at_server_cold_start", new=MagicMock()) as cold:
|
||||||
|
self.server.run_init_hooks("reload")
|
||||||
|
self.server.run_init_hooks("reset")
|
||||||
|
self.server.run_init_hooks("shutdown")
|
||||||
|
|
||||||
evennia.at_server_reload_start = MagicMock()
|
for obj in self.objects:
|
||||||
evennia.at_server_cold_start = MagicMock()
|
obj.at_init.assert_called()
|
||||||
|
|
||||||
evennia.run_init_hooks("reload")
|
for hook in (reload, cold):
|
||||||
evennia.run_init_hooks("reset")
|
hook.assert_called()
|
||||||
evennia.run_init_hooks("shutdown")
|
|
||||||
|
|
||||||
self.acct1.at_init.assert_called()
|
|
||||||
self.acct2.at_init.assert_called()
|
|
||||||
self.obj1.at_init.assert_called()
|
|
||||||
self.obj2.at_init.assert_called()
|
|
||||||
self.chan1.at_init.assert_called()
|
|
||||||
self.chan2.at_init.assert_called()
|
|
||||||
self.script1.at_init.assert_called()
|
|
||||||
self.script2.at_init.assert_called()
|
|
||||||
|
|
||||||
evennia.at_server_reload_start.assert_called()
|
|
||||||
evennia.at_server_cold_start.assert_called()
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue