mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
149 lines
4.6 KiB
Python
149 lines
4.6 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
"""
|
|
Testing various individual functionalities in the server package.
|
|
|
|
"""
|
|
import unittest
|
|
import gc
|
|
import weakref
|
|
|
|
from django.test import TestCase
|
|
from django.test.runner import DiscoverRunner
|
|
|
|
from evennia.server.throttle import Throttle
|
|
from evennia.server.serversession import ServerSession
|
|
from evennia.utils.test_resources import BaseEvenniaTest
|
|
|
|
from ..deprecations import check_errors
|
|
|
|
|
|
class MockSettings(object):
|
|
"""
|
|
Class for simulating django.conf.settings. Created with a single value, and then sets the required
|
|
WEBSERVER_ENABLED setting to True or False depending if we're testing WEBSERVER_PORTS.
|
|
"""
|
|
|
|
def __init__(self, setting, value=None):
|
|
setattr(self, setting, value)
|
|
if setting == "WEBSERVER_PORTS":
|
|
self.WEBSERVER_ENABLED = True
|
|
else:
|
|
self.WEBSERVER_ENABLED = False
|
|
|
|
|
|
class TestDeprecations(TestCase):
|
|
"""
|
|
Class for testing deprecations.check_errors.
|
|
"""
|
|
|
|
deprecated_settings = (
|
|
"CMDSET_DEFAULT",
|
|
"CMDSET_OOC",
|
|
"BASE_COMM_TYPECLASS",
|
|
"COMM_TYPECLASS_PATHS",
|
|
"CHARACTER_DEFAULT_HOME",
|
|
"OBJECT_TYPECLASS_PATHS",
|
|
"SCRIPT_TYPECLASS_PATHS",
|
|
"ACCOUNT_TYPECLASS_PATHS",
|
|
"CHANNEL_TYPECLASS_PATHS",
|
|
"SEARCH_MULTIMATCH_SEPARATOR",
|
|
"TIME_SEC_PER_MIN",
|
|
"TIME_MIN_PER_HOUR",
|
|
"TIME_HOUR_PER_DAY",
|
|
"TIME_DAY_PER_WEEK",
|
|
"TIME_WEEK_PER_MONTH",
|
|
"TIME_MONTH_PER_YEAR",
|
|
"GAME_DIRECTORY_LISTING",
|
|
)
|
|
|
|
def test_check_errors(self):
|
|
"""
|
|
All settings in deprecated_settings should raise a DeprecationWarning if they exist.
|
|
WEBSERVER_PORTS raises an error if the iterable value passed does not have a tuple as its
|
|
first element.
|
|
"""
|
|
for setting in self.deprecated_settings:
|
|
self.assertRaises(DeprecationWarning, check_errors, MockSettings(setting))
|
|
# test check for WEBSERVER_PORTS having correct value
|
|
self.assertRaises(
|
|
DeprecationWarning, check_errors, MockSettings("WEBSERVER_PORTS", value=["not a tuple"])
|
|
)
|
|
|
|
|
|
class ThrottleTest(BaseEvenniaTest):
|
|
"""
|
|
Class for testing the connection/IP throttle.
|
|
"""
|
|
|
|
def test_throttle(self):
|
|
ips = ("256.256.256.257", "257.257.257.257", "258.258.258.258")
|
|
kwargs = {"name": "testing", "limit": 5, "timeout": 15 * 60}
|
|
|
|
throttle = Throttle(**kwargs)
|
|
|
|
for ip in ips:
|
|
# Throttle should not be engaged by default
|
|
self.assertFalse(throttle.check(ip))
|
|
|
|
# Pretend to fail a bunch of events
|
|
for x in range(50):
|
|
obj = throttle.update(ip)
|
|
self.assertFalse(obj)
|
|
|
|
# Next ones should be blocked
|
|
self.assertTrue(throttle.check(ip))
|
|
|
|
for x in range(throttle.cache_size * 2):
|
|
obj = throttle.update(ip)
|
|
self.assertFalse(obj)
|
|
|
|
# Should still be blocked
|
|
self.assertTrue(throttle.check(ip))
|
|
|
|
# Number of values should be limited by cache size
|
|
self.assertEqual(throttle.cache_size, len(throttle.get(ip)))
|
|
|
|
cache = throttle.get()
|
|
|
|
# Make sure there are entries for each IP
|
|
self.assertEqual(len(ips), len(cache.keys()))
|
|
|
|
# There should only be (cache_size * num_ips) total in the Throttle cache
|
|
self.assertEqual(sum([len(cache[x]) for x in cache.keys()]), throttle.cache_size * len(ips))
|
|
|
|
# Make sure the cache is populated
|
|
self.assertTrue(throttle.get())
|
|
|
|
# Remove the test IPs from the throttle cache
|
|
# (in case persistent storage was configured by the user)
|
|
for ip in ips:
|
|
self.assertTrue(throttle.remove(ip))
|
|
|
|
# Make sure the cache is empty
|
|
self.assertFalse(throttle.get())
|
|
|
|
|
|
class TestServerSessionAttributeLifecycle(BaseEvenniaTest):
|
|
"""
|
|
Regression test for the AttributeHandler/ServerSession retention discussed in #3225.
|
|
"""
|
|
|
|
def test_serversession_attributes_do_not_prevent_gc(self):
|
|
refs = []
|
|
|
|
for idx in range(50):
|
|
sess = ServerSession()
|
|
sess.init_session("telnet", "127.0.0.1", sessionhandler=None)
|
|
# Force-create the lazy handler and store an in-memory Attribute.
|
|
sess.attributes.add("last_cmd", f"quit-{idx}")
|
|
refs.append(weakref.ref(sess))
|
|
sess = None
|
|
|
|
gc.collect()
|
|
gc.collect()
|
|
|
|
self.assertFalse(
|
|
any(ref() is not None for ref in refs),
|
|
"ServerSession instances should be collectable after AttributeHandler use.",
|
|
)
|