Skip to content

Commit

Permalink
Merge pull request #15 from threat9/tcp-service
Browse files Browse the repository at this point in the history
WIP: TCPServiceMock
  • Loading branch information
lucyoa authored Jun 3, 2018
2 parents 95bf6b4 + 267c82a commit e8fdd29
Show file tree
Hide file tree
Showing 11 changed files with 102 additions and 18 deletions.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
install_requires=[
"click",
"Faker",
"flask",
"flask>=1.0.0",
"gunicorn",
"pyopenssl",
"requests",
Expand Down
23 changes: 23 additions & 0 deletions tests/service_mocks/test_tcp_service_mock.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import socket

from threat9_test_bed.service_mocks import TCPServiceMock


def test_tcp_service_mock_add_banner():
with TCPServiceMock("127.0.0.1", 8023) as target:
assert target.host == "127.0.0.1"
assert target.port == 8023

mocked_doo = target.get_command_mock(b"doo")
mocked_doo.return_value = b"where are you?"
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((target.host, target.port))
s.send(b"doo")
assert s.recv(1024) == b"where are you?"

mocked_scoo = target.get_command_mock(b"scoo")
mocked_scoo.return_value = b"bee"
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((target.host, target.port))
s.send(b"scoo")
assert s.recv(1024) == b"bee"
22 changes: 9 additions & 13 deletions threat9_test_bed/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import click

from .http_service.app import app
from .http_service.gunicorn_server import GunicornServer
from .scenarios import HttpScenario, TelnetScenario
from .service_mocks.http_service_mock import WerkzeugBasedHttpService
from .telnet_service.protocol import TelnetServerClientProtocol
from .telnet_service.telnet_server import TelnetServer

Expand All @@ -30,13 +30,11 @@ def run_http_server(scenario, port):
app.config.update(
SCENARIO=HttpScenario[scenario],
)
GunicornServer(
WerkzeugBasedHttpService(
app=app,
bind=f"127.0.0.1:{port}",
worker_class="gthread",
threads=8,
accesslog="-",
).run()
host=f"127.0.0.1",
port=port,
).start()
logger.debug(f"`http` server has been started on port {port}.")


Expand All @@ -54,14 +52,12 @@ def run_https_server(scenario, port):
app.config.update(
SCENARIO=HttpScenario[scenario],
)
GunicornServer(
WerkzeugBasedHttpService(
app=app,
bind=f"127.0.0.1:{port}",
worker_class="gthread",
threads=8,
host=f"127.0.0.1",
port=port,
ssl=True,
accesslog="-",
).run()
).start()
logger.debug(f"`https` server has been started on port {port}.")


Expand Down
1 change: 1 addition & 0 deletions threat9_test_bed/http_service/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ def redirect_():

def timeout():
time.sleep(60 * 60)
return found()


def error():
Expand Down
2 changes: 2 additions & 0 deletions threat9_test_bed/service_mocks/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
from .http_scenario_service import HttpScenarioService # noqa: F401
from .http_service_mock import HttpServiceMock # noqa: F401
from .tcp_service_mock import TCPServiceMock # noqa: F401
from .telnet_service_mock import TelnetServiceMock # noqa: F401
2 changes: 1 addition & 1 deletion threat9_test_bed/service_mocks/base_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def __exit__(self, exc_type, exc_val, exc_tb):
logger.debug(f"{self} has been terminated.")

@staticmethod
def dib_port(port=0) -> (int, socket.socket):
def dib_port(port: int = 0) -> (int, socket.socket):
socket_ = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket_.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
socket_.bind(("", port))
Expand Down
4 changes: 2 additions & 2 deletions threat9_test_bed/service_mocks/http_scenario_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

from ..http_service.app import app
from ..scenarios import HttpScenario
from .base_http_service import GunicornBasedHttpService
from .base_http_service import WerkzeugBasedHttpService

logger = logging.getLogger(__name__)


class HttpScenarioService(GunicornBasedHttpService):
class HttpScenarioService(WerkzeugBasedHttpService):
def __init__(self, host: str, port: int, scenario: HttpScenario):
app.config.update(SCENARIO=scenario)
super().__init__(host, port, app)
30 changes: 30 additions & 0 deletions threat9_test_bed/service_mocks/tcp_service_mock.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from logging import getLogger
import threading
from unittest import mock

from ..tcp_service.tcp_server import TCPHandler, TCPServer
from .base_service import BaseService

logger = getLogger(__name__)


class TCPServiceMock(BaseService):

def __init__(self, host: str, port: int):
super().__init__(host, port)
self.server = TCPServer((self.host, self.port), TCPHandler, False)
self.server_thread = threading.Thread(target=self.server.serve_forever)

def start(self):
self.server.server_bind()
self.server.server_activate()
self.server_thread.start()

def teardown(self):
self.server.shutdown()
self.server_thread.join()
self.server.server_close()

def get_command_mock(self, command: bytes) -> mock.Mock:
logger.debug(f"{self} mock for '{command}' has been added.")
return self.server.get_command_mock(command)
2 changes: 1 addition & 1 deletion threat9_test_bed/service_mocks/telnet_service_mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from ..scenarios import TelnetScenario
from ..telnet_service.protocol import TelnetServerClientProtocol
from ..telnet_service.telnet_server import TelnetServer
from .base_http_service import BaseService
from .base_service import BaseService

logger = logging.getLogger(__name__)

Expand Down
Empty file.
32 changes: 32 additions & 0 deletions threat9_test_bed/tcp_service/tcp_server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from logging import getLogger
import socketserver
from unittest import mock

logger = getLogger(__name__)


class TCPServer(socketserver.ThreadingTCPServer):
allow_reuse_address = True

def __init__(
self,
server_address,
request_handler_class,
bind_and_activate=True,
):
super().__init__(
server_address, request_handler_class, bind_and_activate,
)
self.handlers = {}

def get_command_mock(self, command: bytes) -> mock.Mock:
mocked_handler = mock.MagicMock(name=command)
self.handlers[command] = mocked_handler
return mocked_handler


class TCPHandler(socketserver.BaseRequestHandler):
def handle(self):
data = self.request.recv(1024)
handler = self.server.handlers[data]
self.request.sendall(handler())

0 comments on commit e8fdd29

Please sign in to comment.