From fe969111ce274aab16d6baf2edd0adebc359e8be Mon Sep 17 00:00:00 2001 From: Tehom Date: Tue, 16 Oct 2018 19:51:43 -0400 Subject: [PATCH 1/8] Add stub for testing Telnet --- evennia/server/portal/tests.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/evennia/server/portal/tests.py b/evennia/server/portal/tests.py index be400144c6..b09f71ae03 100644 --- a/evennia/server/portal/tests.py +++ b/evennia/server/portal/tests.py @@ -11,6 +11,11 @@ except ImportError: import string from evennia.server.portal import irc +from twisted.test import proto_helpers +from twisted.trial.unittest import TestCase as TwistedTestCase + +from .telnet import TelnetServerFactory + class TestIRC(TestCase): @@ -73,3 +78,15 @@ class TestIRC(TestCase): s = r'|wthis|Xis|gis|Ma|C|complex|*string' self.assertEqual(irc.parse_irc_to_ansi(irc.parse_ansi_to_irc(s)), s) + + +class TestTelnet(TwistedTestCase): + def setUp(self): + super(TestTelnet, self).setUp() + factory = TelnetServerFactory() + self.proto = factory.buildProtocol(("localhost", 0)) + self.transport = proto_helpers.StringTransport() + + def test_connect(self): + self.proto.makeConnection(self.transport) + # TODO: Add rest of stuff for testing connection From 6b96e84fd03039f0512ec947ae29841409c96618 Mon Sep 17 00:00:00 2001 From: Henddher Pedroza Date: Tue, 16 Oct 2018 19:31:10 -0500 Subject: [PATCH 2/8] Tests for @desc obj= --- evennia/commands/default/tests.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/evennia/commands/default/tests.py b/evennia/commands/default/tests.py index a3be98984a..6010b008da 100644 --- a/evennia/commands/default/tests.py +++ b/evennia/commands/default/tests.py @@ -263,6 +263,20 @@ class TestBuilding(CommandTest): def test_desc(self): self.call(building.CmdDesc(), "Obj2=TestDesc", "The description was set on Obj2(#5).") + def test_empty_desc(self): + o2d = self.obj2.db.desc + r1d = self.room1.db.desc + self.call(building.CmdDesc(), "Obj2=", "The description was set on Obj2(#5).") + assert self.obj2.db.desc == '' + assert self.room1.db.desc == r1d + + def test_desc_default_to_room(self): + o2d = self.obj2.db.desc + r1d = self.room1.db.desc + self.call(building.CmdDesc(), "Obj2", "The description was set on Room(#1).") + assert self.obj2.db.desc == o2d + assert self.room1.db.desc == 'Obj2' + def test_wipe(self): confirm = building.CmdDestroy.confirm building.CmdDestroy.confirm = False @@ -446,4 +460,4 @@ class TestUnconnectedCommand(CommandTest): settings.SERVERNAME, datetime.datetime.fromtimestamp(gametime.SERVER_START_TIME).ctime(), SESSIONS.account_count(), utils.get_evennia_version()) - self.call(unloggedin.CmdUnconnectedInfo(), "", expected) \ No newline at end of file + self.call(unloggedin.CmdUnconnectedInfo(), "", expected) From 40a37e501f1ffb94f448e886a13220abf402caa0 Mon Sep 17 00:00:00 2001 From: Tehom Date: Tue, 16 Oct 2018 20:33:12 -0400 Subject: [PATCH 3/8] Add some cleanup steps to prevent unclean reactor --- evennia/server/portal/telnet.py | 2 +- evennia/server/portal/tests.py | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/evennia/server/portal/telnet.py b/evennia/server/portal/telnet.py index 955ea5e918..83e2fa03a2 100644 --- a/evennia/server/portal/telnet.py +++ b/evennia/server/portal/telnet.py @@ -84,7 +84,7 @@ class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session): from evennia.utils.utils import delay # timeout the handshakes in case the client doesn't reply at all - delay(2, callback=self.handshake_done, timeout=True) + self._handshake_delay = delay(2, callback=self.handshake_done, timeout=True) # TCP/IP keepalive watches for dead links self.transport.setTcpKeepAlive(1) diff --git a/evennia/server/portal/tests.py b/evennia/server/portal/tests.py index b09f71ae03..53a732f121 100644 --- a/evennia/server/portal/tests.py +++ b/evennia/server/portal/tests.py @@ -8,13 +8,15 @@ try: except ImportError: import unittest +from mock import Mock import string from evennia.server.portal import irc from twisted.test import proto_helpers from twisted.trial.unittest import TestCase as TwistedTestCase -from .telnet import TelnetServerFactory +from .telnet import TelnetServerFactory, TelnetProtocol +from .portal import PORTAL_SESSIONS class TestIRC(TestCase): @@ -84,9 +86,19 @@ class TestTelnet(TwistedTestCase): def setUp(self): super(TestTelnet, self).setUp() factory = TelnetServerFactory() + factory.protocol = TelnetProtocol + factory.sessionhandler = PORTAL_SESSIONS + factory.sessionhandler.portal = Mock() self.proto = factory.buildProtocol(("localhost", 0)) self.transport = proto_helpers.StringTransport() + self.addCleanup(factory.sessionhandler.disconnect_all) def test_connect(self): - self.proto.makeConnection(self.transport) + self.transport.client = ["localhost"] + self.transport.setTcpKeepAlive = Mock() + d = self.proto.makeConnection(self.transport) # TODO: Add rest of stuff for testing connection + # clean up to prevent Unclean reactor + self.proto.nop_keep_alive.stop() + self.proto._handshake_delay.cancel() + return d From dc44dc0176acdb6404f116a798393fae9134f85f Mon Sep 17 00:00:00 2001 From: Henddher Pedroza Date: Tue, 16 Oct 2018 19:49:19 -0500 Subject: [PATCH 4/8] In @desc command, validate rhs based on = sign present in orig args. Default MUX parsing assigns None to rhs if there is nothing on the right of the = sign. --- evennia/commands/default/building.py | 4 ++-- evennia/commands/default/tests.py | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/evennia/commands/default/building.py b/evennia/commands/default/building.py index 0afeea8fe5..aaafea30ac 100644 --- a/evennia/commands/default/building.py +++ b/evennia/commands/default/building.py @@ -589,12 +589,12 @@ class CmdDesc(COMMAND_DEFAULT_CLASS): self.edit_handler() return - if self.rhs: + if '=' in self.args: # We have an = obj = caller.search(self.lhs) if not obj: return - desc = self.rhs + desc = self.rhs or '' else: obj = caller.location or self.msg("|rYou can't describe oblivion.|n") if not obj: diff --git a/evennia/commands/default/tests.py b/evennia/commands/default/tests.py index 6010b008da..6e5877608c 100644 --- a/evennia/commands/default/tests.py +++ b/evennia/commands/default/tests.py @@ -264,6 +264,9 @@ class TestBuilding(CommandTest): self.call(building.CmdDesc(), "Obj2=TestDesc", "The description was set on Obj2(#5).") def test_empty_desc(self): + """ + empty desc sets desc as '' + """ o2d = self.obj2.db.desc r1d = self.room1.db.desc self.call(building.CmdDesc(), "Obj2=", "The description was set on Obj2(#5).") @@ -271,6 +274,7 @@ class TestBuilding(CommandTest): assert self.room1.db.desc == r1d def test_desc_default_to_room(self): + """no rhs changes room's desc""" o2d = self.obj2.db.desc r1d = self.room1.db.desc self.call(building.CmdDesc(), "Obj2", "The description was set on Room(#1).") From e08efc68dc637235592aa25ca2fd4b2951544baa Mon Sep 17 00:00:00 2001 From: Henddher Pedroza Date: Tue, 16 Oct 2018 20:09:17 -0500 Subject: [PATCH 5/8] Harden assertions --- evennia/commands/default/tests.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/evennia/commands/default/tests.py b/evennia/commands/default/tests.py index 6e5877608c..1b97a59f9f 100644 --- a/evennia/commands/default/tests.py +++ b/evennia/commands/default/tests.py @@ -270,7 +270,7 @@ class TestBuilding(CommandTest): o2d = self.obj2.db.desc r1d = self.room1.db.desc self.call(building.CmdDesc(), "Obj2=", "The description was set on Obj2(#5).") - assert self.obj2.db.desc == '' + assert self.obj2.db.desc == '' and self.obj2.db.desc != o2d assert self.room1.db.desc == r1d def test_desc_default_to_room(self): @@ -279,7 +279,7 @@ class TestBuilding(CommandTest): r1d = self.room1.db.desc self.call(building.CmdDesc(), "Obj2", "The description was set on Room(#1).") assert self.obj2.db.desc == o2d - assert self.room1.db.desc == 'Obj2' + assert self.room1.db.desc == 'Obj2' and self.room1.db.desc != r1d def test_wipe(self): confirm = building.CmdDestroy.confirm From b4383592016e532ebedb315616353712988bd257 Mon Sep 17 00:00:00 2001 From: Tehom Date: Wed, 17 Oct 2018 01:50:57 -0400 Subject: [PATCH 6/8] Add test of NOGOAHEAD --- evennia/server/portal/tests.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/evennia/server/portal/tests.py b/evennia/server/portal/tests.py index 53a732f121..4142ca297e 100644 --- a/evennia/server/portal/tests.py +++ b/evennia/server/portal/tests.py @@ -12,11 +12,13 @@ from mock import Mock import string from evennia.server.portal import irc +from twisted.conch.telnet import IAC, NOP, LINEMODE, GA, WILL, WONT, ECHO, NULL, DONT from twisted.test import proto_helpers from twisted.trial.unittest import TestCase as TwistedTestCase from .telnet import TelnetServerFactory, TelnetProtocol from .portal import PORTAL_SESSIONS +from .suppress_ga import SUPPRESS_GA class TestIRC(TestCase): @@ -98,6 +100,10 @@ class TestTelnet(TwistedTestCase): self.transport.setTcpKeepAlive = Mock() d = self.proto.makeConnection(self.transport) # TODO: Add rest of stuff for testing connection + self.assertTrue(self.proto.protocol_flags["NOGOAHEAD"]) + self.proto.dataReceived(IAC + DONT+ SUPPRESS_GA) + self.assertFalse(self.proto.protocol_flags["NOGOAHEAD"]) + self.assertEqual(self.proto.handshakes, 7) # clean up to prevent Unclean reactor self.proto.nop_keep_alive.stop() self.proto._handshake_delay.cancel() From ef0e0e0b4c6e2827f8832512632c580280c1af28 Mon Sep 17 00:00:00 2001 From: Tehom Date: Wed, 17 Oct 2018 12:49:48 -0400 Subject: [PATCH 7/8] Add various simple tests for different handshakes --- evennia/server/portal/tests.py | 49 +++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/evennia/server/portal/tests.py b/evennia/server/portal/tests.py index 4142ca297e..791e5172a4 100644 --- a/evennia/server/portal/tests.py +++ b/evennia/server/portal/tests.py @@ -12,13 +12,19 @@ from mock import Mock import string from evennia.server.portal import irc -from twisted.conch.telnet import IAC, NOP, LINEMODE, GA, WILL, WONT, ECHO, NULL, DONT +from twisted.conch.telnet import IAC, WILL, DONT, SB, SE, NAWS, DO from twisted.test import proto_helpers from twisted.trial.unittest import TestCase as TwistedTestCase from .telnet import TelnetServerFactory, TelnetProtocol from .portal import PORTAL_SESSIONS from .suppress_ga import SUPPRESS_GA +from .naws import DEFAULT_HEIGHT, DEFAULT_WIDTH +from .ttype import TTYPE, IS +from .mccp import MCCP +from .mssp import MSSP +from .mxp import MXP +from .telnet_oob import MSDP, MSDP_VAL, MSDP_VAR class TestIRC(TestCase): @@ -95,15 +101,50 @@ class TestTelnet(TwistedTestCase): self.transport = proto_helpers.StringTransport() self.addCleanup(factory.sessionhandler.disconnect_all) - def test_connect(self): + def test_mudlet_ttype(self): self.transport.client = ["localhost"] self.transport.setTcpKeepAlive = Mock() d = self.proto.makeConnection(self.transport) - # TODO: Add rest of stuff for testing connection + # test suppress_ga self.assertTrue(self.proto.protocol_flags["NOGOAHEAD"]) - self.proto.dataReceived(IAC + DONT+ SUPPRESS_GA) + self.proto.dataReceived(IAC + DONT + SUPPRESS_GA) self.assertFalse(self.proto.protocol_flags["NOGOAHEAD"]) self.assertEqual(self.proto.handshakes, 7) + # test naws + self.assertEqual(self.proto.protocol_flags['SCREENWIDTH'], {0: DEFAULT_WIDTH}) + self.assertEqual(self.proto.protocol_flags['SCREENHEIGHT'], {0: DEFAULT_HEIGHT}) + self.proto.dataReceived(IAC + WILL + NAWS) + self.proto.dataReceived([IAC, SB, NAWS, '', 'x', '', 'd', IAC, SE]) + self.assertEqual(self.proto.protocol_flags['SCREENWIDTH'][0], 120) + self.assertEqual(self.proto.protocol_flags['SCREENHEIGHT'][0], 100) + self.assertEqual(self.proto.handshakes, 6) + # test ttype + self.assertTrue(self.proto.protocol_flags["FORCEDENDLINE"]) + self.assertFalse(self.proto.protocol_flags["TTYPE"]) + self.assertTrue(self.proto.protocol_flags["ANSI"]) + self.proto.dataReceived(IAC + WILL + TTYPE) + self.proto.dataReceived([IAC, SB, TTYPE, IS, "MUDLET", IAC, SE]) + self.assertTrue(self.proto.protocol_flags["XTERM256"]) + self.assertEqual(self.proto.protocol_flags["CLIENTNAME"], "MUDLET") + self.proto.dataReceived([IAC, SB, TTYPE, IS, "XTERM", IAC, SE]) + self.proto.dataReceived([IAC, SB, TTYPE, IS, "MTTS 137", IAC, SE]) + self.assertEqual(self.proto.handshakes, 5) + # test mccp + self.proto.dataReceived(IAC + DONT + MCCP) + self.assertFalse(self.proto.protocol_flags['MCCP']) + self.assertEqual(self.proto.handshakes, 4) + # test mssp + self.proto.dataReceived(IAC + DONT + MSSP) + self.assertEqual(self.proto.handshakes, 3) + # test oob + self.proto.dataReceived(IAC + DO + MSDP) + self.proto.dataReceived([IAC, SB, MSDP, MSDP_VAR, "LIST", MSDP_VAL, "COMMANDS", IAC, SE]) + self.assertTrue(self.proto.protocol_flags['OOB']) + self.assertEqual(self.proto.handshakes, 2) + # test mxp + self.proto.dataReceived(IAC + DONT + MXP) + self.assertFalse(self.proto.protocol_flags['MXP']) + self.assertEqual(self.proto.handshakes, 1) # clean up to prevent Unclean reactor self.proto.nop_keep_alive.stop() self.proto._handshake_delay.cancel() From 788120706228d9c62d08cab1fe037bae6dc9fd3c Mon Sep 17 00:00:00 2001 From: Tehom Date: Wed, 17 Oct 2018 22:43:33 -0400 Subject: [PATCH 8/8] Add tests for memplot --- evennia/server/profiling/memplot.py | 6 +++--- evennia/server/profiling/tests.py | 21 ++++++++++++++++++++- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/evennia/server/profiling/memplot.py b/evennia/server/profiling/memplot.py index e8d7e76b12..c6a227a370 100644 --- a/evennia/server/profiling/memplot.py +++ b/evennia/server/profiling/memplot.py @@ -13,14 +13,14 @@ import time # TODO! #sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))) #os.environ['DJANGO_SETTINGS_MODULE'] = 'game.settings' -import ev -from evennia.utils.idmapper import base as _idmapper +import evennia +from evennia.utils.idmapper import models as _idmapper LOGFILE = "logs/memoryusage.log" INTERVAL = 30 # log every 30 seconds -class Memplot(ev.Script): +class Memplot(evennia.DefaultScript): """ Describes a memory plotting action. diff --git a/evennia/server/profiling/tests.py b/evennia/server/profiling/tests.py index b3e9fba8d5..cca4e0d99b 100644 --- a/evennia/server/profiling/tests.py +++ b/evennia/server/profiling/tests.py @@ -1,7 +1,8 @@ from django.test import TestCase -from mock import Mock +from mock import Mock, patch, mock_open from .dummyrunner_settings import (c_creates_button, c_creates_obj, c_digs, c_examines, c_help, c_idles, c_login, c_login_nodig, c_logout, c_looks, c_moves, c_moves_n, c_moves_s, c_socialize) +import memplot class TestDummyrunnerSettings(TestCase): @@ -91,3 +92,21 @@ class TestDummyrunnerSettings(TestCase): def test_c_move_s(self): self.assertEqual(c_moves_s(self.client), "south") + + +class TestMemPlot(TestCase): + @patch.object(memplot, "_idmapper") + @patch.object(memplot, "os") + @patch.object(memplot, "open", new_callable=mock_open, create=True) + @patch.object(memplot, "time") + def test_memplot(self, mock_time, mocked_open, mocked_os, mocked_idmapper): + from evennia.utils.create import create_script + mocked_idmapper.cache_size.return_value = (9, 5000) + mock_time.time = Mock(return_value=6000.0) + script = create_script(memplot.Memplot) + script.db.starttime = 0.0 + mocked_os.popen.read.return_value = 5000.0 + script.at_repeat() + handle = mocked_open() + handle.write.assert_called_with('100.0, 0.001, 0.001, 9\n') + script.stop()