diff --git a/newsfragments/3041.feature b/newsfragments/3041.feature new file mode 100644 index 000000000..b78695126 --- /dev/null +++ b/newsfragments/3041.feature @@ -0,0 +1 @@ +End-to-end in-memory tests for websocket features \ No newline at end of file diff --git a/src/allmydata/_auto_deps.py b/src/allmydata/_auto_deps.py index 38b98e59c..415eb02bd 100644 --- a/src/allmydata/_auto_deps.py +++ b/src/allmydata/_auto_deps.py @@ -107,6 +107,9 @@ install_requires = [ # A great way to define types of values. "attrs >= 18.2.0", + + # WebSocket library for twisted and asyncio + "autobahn >= 19.5.2", ] # Includes some indirect dependencies, but does not include allmydata. diff --git a/src/allmydata/test/test_websocket_logs.py b/src/allmydata/test/test_websocket_logs.py new file mode 100644 index 000000000..983613a28 --- /dev/null +++ b/src/allmydata/test/test_websocket_logs.py @@ -0,0 +1,54 @@ +import json + +from twisted.trial import unittest +from twisted.internet.defer import inlineCallbacks + +from eliot import log_call + +from autobahn.twisted.testing import create_memory_agent, MemoryReactorClockResolver, create_pumper + +from allmydata.web.logs import TokenAuthenticatedWebSocketServerProtocol + + +class TestStreamingLogs(unittest.TestCase): + """ + Test websocket streaming of logs + """ + + def setUp(self): + self.reactor = MemoryReactorClockResolver() + self.pumper = create_pumper() + self.agent = create_memory_agent(self.reactor, self.pumper, TokenAuthenticatedWebSocketServerProtocol) + return self.pumper.start() + + def tearDown(self): + return self.pumper.stop() + + @inlineCallbacks + def test_one_log(self): + """ + write a single Eliot log and see it streamed via websocket + """ + + proto = yield self.agent.open( + transport_config=u"ws://localhost:1234/ws", + options={}, + ) + + messages = [] + def got_message(msg, is_binary=False): + messages.append(json.loads(msg)) + proto.on("message", got_message) + + @log_call(action_type=u"test:cli:magic-folder:cleanup") + def do_a_thing(): + pass + + do_a_thing() + + proto.transport.loseConnection() + yield proto.is_closed + + self.assertEqual(len(messages), 2) + self.assertEqual("started", messages[0]["action_status"]) + self.assertEqual("succeeded", messages[1]["action_status"])