mirror of
https://github.com/krkn-chaos/krkn.git
synced 2026-02-14 18:10:00 +00:00
Some checks failed
Functional & Unit Tests / Functional & Unit Tests (push) Failing after 4m2s
Functional & Unit Tests / Generate Coverage Badge (push) Has been skipped
Signed-off-by: Paige Patton <prubenda@redhat.com>
386 lines
13 KiB
Python
386 lines
13 KiB
Python
#!/usr/bin/env python3
|
|
|
|
"""
|
|
Test suite for SimpleHTTPRequestHandler class
|
|
|
|
Usage:
|
|
python -m coverage run -a -m unittest tests/test_server.py -v
|
|
|
|
Assisted By: Claude Code
|
|
"""
|
|
|
|
import unittest
|
|
from unittest.mock import Mock, patch, MagicMock
|
|
from io import BytesIO
|
|
|
|
import server
|
|
from server import SimpleHTTPRequestHandler
|
|
|
|
|
|
class TestSimpleHTTPRequestHandler(unittest.TestCase):
|
|
|
|
def setUp(self):
|
|
"""
|
|
Set up test fixtures for SimpleHTTPRequestHandler
|
|
"""
|
|
# Reset the global server_status before each test
|
|
server.server_status = ""
|
|
# Reset the requests_served counter
|
|
SimpleHTTPRequestHandler.requests_served = 0
|
|
|
|
# Create a mock request
|
|
self.mock_request = MagicMock()
|
|
self.mock_client_address = ('127.0.0.1', 12345)
|
|
self.mock_server = MagicMock()
|
|
|
|
def _create_handler(self, method='GET', path='/'):
|
|
"""
|
|
Helper method to create a handler instance with mocked request
|
|
"""
|
|
# Create a mock request with proper attributes
|
|
mock_request = MagicMock()
|
|
mock_request.makefile.return_value = BytesIO(
|
|
f"{method} {path} HTTP/1.1\r\n\r\n".encode('utf-8')
|
|
)
|
|
|
|
# Create handler
|
|
handler = SimpleHTTPRequestHandler(
|
|
mock_request,
|
|
self.mock_client_address,
|
|
self.mock_server
|
|
)
|
|
|
|
# Mock the wfile (write file) for response
|
|
handler.wfile = BytesIO()
|
|
|
|
return handler
|
|
|
|
def test_do_GET_root_path_calls_do_status(self):
|
|
"""
|
|
Test do_GET with root path calls do_status
|
|
"""
|
|
handler = self._create_handler('GET', '/')
|
|
|
|
with patch.object(handler, 'do_status') as mock_do_status:
|
|
handler.do_GET()
|
|
mock_do_status.assert_called_once()
|
|
|
|
def test_do_GET_non_root_path_does_nothing(self):
|
|
"""
|
|
Test do_GET with non-root path does not call do_status
|
|
"""
|
|
handler = self._create_handler('GET', '/other')
|
|
|
|
with patch.object(handler, 'do_status') as mock_do_status:
|
|
handler.do_GET()
|
|
mock_do_status.assert_not_called()
|
|
|
|
def test_do_status_sends_200_response(self):
|
|
"""
|
|
Test do_status sends 200 status code
|
|
"""
|
|
server.server_status = "TEST_STATUS"
|
|
handler = self._create_handler()
|
|
|
|
with patch.object(handler, 'send_response') as mock_send_response:
|
|
with patch.object(handler, 'end_headers'):
|
|
handler.do_status()
|
|
mock_send_response.assert_called_once_with(200)
|
|
|
|
def test_do_status_writes_server_status(self):
|
|
"""
|
|
Test do_status writes server_status to response
|
|
"""
|
|
server.server_status = "RUNNING"
|
|
handler = self._create_handler()
|
|
|
|
with patch.object(handler, 'send_response'):
|
|
with patch.object(handler, 'end_headers'):
|
|
handler.do_status()
|
|
|
|
# Check that the status was written to wfile
|
|
response_content = handler.wfile.getvalue().decode('utf-8')
|
|
self.assertEqual(response_content, "RUNNING")
|
|
|
|
def test_do_status_increments_requests_served(self):
|
|
"""
|
|
Test do_status increments requests_served counter
|
|
"""
|
|
# Note: Creating a handler increments the counter by 1
|
|
# Then do_status increments it again
|
|
SimpleHTTPRequestHandler.requests_served = 0
|
|
handler = self._create_handler()
|
|
initial_count = SimpleHTTPRequestHandler.requests_served
|
|
|
|
with patch.object(handler, 'send_response'):
|
|
with patch.object(handler, 'end_headers'):
|
|
handler.do_status()
|
|
|
|
self.assertEqual(
|
|
SimpleHTTPRequestHandler.requests_served,
|
|
initial_count + 1
|
|
)
|
|
|
|
def test_do_status_multiple_requests_increment_counter(self):
|
|
"""
|
|
Test multiple do_status calls increment counter correctly
|
|
"""
|
|
SimpleHTTPRequestHandler.requests_served = 0
|
|
|
|
for i in range(5):
|
|
handler = self._create_handler()
|
|
with patch.object(handler, 'send_response'):
|
|
with patch.object(handler, 'end_headers'):
|
|
handler.do_status()
|
|
|
|
# Each iteration: handler creation increments by 1, do_status increments by 1
|
|
# Total: 5 * 2 = 10
|
|
self.assertEqual(SimpleHTTPRequestHandler.requests_served, 10)
|
|
|
|
def test_do_POST_STOP_path_calls_set_stop(self):
|
|
"""
|
|
Test do_POST with /STOP path calls set_stop
|
|
"""
|
|
handler = self._create_handler('POST', '/STOP')
|
|
|
|
with patch.object(handler, 'set_stop') as mock_set_stop:
|
|
handler.do_POST()
|
|
mock_set_stop.assert_called_once()
|
|
|
|
def test_do_POST_RUN_path_calls_set_run(self):
|
|
"""
|
|
Test do_POST with /RUN path calls set_run
|
|
"""
|
|
handler = self._create_handler('POST', '/RUN')
|
|
|
|
with patch.object(handler, 'set_run') as mock_set_run:
|
|
handler.do_POST()
|
|
mock_set_run.assert_called_once()
|
|
|
|
def test_do_POST_PAUSE_path_calls_set_pause(self):
|
|
"""
|
|
Test do_POST with /PAUSE path calls set_pause
|
|
"""
|
|
handler = self._create_handler('POST', '/PAUSE')
|
|
|
|
with patch.object(handler, 'set_pause') as mock_set_pause:
|
|
handler.do_POST()
|
|
mock_set_pause.assert_called_once()
|
|
|
|
def test_do_POST_unknown_path_does_nothing(self):
|
|
"""
|
|
Test do_POST with unknown path does not call any setter
|
|
"""
|
|
handler = self._create_handler('POST', '/UNKNOWN')
|
|
|
|
with patch.object(handler, 'set_stop') as mock_set_stop:
|
|
with patch.object(handler, 'set_run') as mock_set_run:
|
|
with patch.object(handler, 'set_pause') as mock_set_pause:
|
|
handler.do_POST()
|
|
mock_set_stop.assert_not_called()
|
|
mock_set_run.assert_not_called()
|
|
mock_set_pause.assert_not_called()
|
|
|
|
def test_set_run_sets_status_to_RUN(self):
|
|
"""
|
|
Test set_run sets global server_status to 'RUN'
|
|
"""
|
|
handler = self._create_handler()
|
|
|
|
with patch.object(handler, 'send_response'):
|
|
with patch.object(handler, 'end_headers'):
|
|
handler.set_run()
|
|
|
|
self.assertEqual(server.server_status, 'RUN')
|
|
|
|
def test_set_run_sends_200_response(self):
|
|
"""
|
|
Test set_run sends 200 status code
|
|
"""
|
|
handler = self._create_handler()
|
|
|
|
with patch.object(handler, 'send_response') as mock_send_response:
|
|
with patch.object(handler, 'end_headers'):
|
|
handler.set_run()
|
|
mock_send_response.assert_called_once_with(200)
|
|
|
|
def test_set_stop_sets_status_to_STOP(self):
|
|
"""
|
|
Test set_stop sets global server_status to 'STOP'
|
|
"""
|
|
handler = self._create_handler()
|
|
|
|
with patch.object(handler, 'send_response'):
|
|
with patch.object(handler, 'end_headers'):
|
|
handler.set_stop()
|
|
|
|
self.assertEqual(server.server_status, 'STOP')
|
|
|
|
def test_set_stop_sends_200_response(self):
|
|
"""
|
|
Test set_stop sends 200 status code
|
|
"""
|
|
handler = self._create_handler()
|
|
|
|
with patch.object(handler, 'send_response') as mock_send_response:
|
|
with patch.object(handler, 'end_headers'):
|
|
handler.set_stop()
|
|
mock_send_response.assert_called_once_with(200)
|
|
|
|
def test_set_pause_sets_status_to_PAUSE(self):
|
|
"""
|
|
Test set_pause sets global server_status to 'PAUSE'
|
|
"""
|
|
handler = self._create_handler()
|
|
|
|
with patch.object(handler, 'send_response'):
|
|
with patch.object(handler, 'end_headers'):
|
|
handler.set_pause()
|
|
|
|
self.assertEqual(server.server_status, 'PAUSE')
|
|
|
|
def test_set_pause_sends_200_response(self):
|
|
"""
|
|
Test set_pause sends 200 status code
|
|
"""
|
|
handler = self._create_handler()
|
|
|
|
with patch.object(handler, 'send_response') as mock_send_response:
|
|
with patch.object(handler, 'end_headers'):
|
|
handler.set_pause()
|
|
mock_send_response.assert_called_once_with(200)
|
|
|
|
def test_requests_served_is_class_variable(self):
|
|
"""
|
|
Test requests_served is shared across all instances
|
|
"""
|
|
SimpleHTTPRequestHandler.requests_served = 0
|
|
|
|
handler1 = self._create_handler() # Increments to 1
|
|
handler2 = self._create_handler() # Increments to 2
|
|
|
|
with patch.object(handler1, 'send_response'):
|
|
with patch.object(handler1, 'end_headers'):
|
|
handler1.do_status() # Increments to 3
|
|
|
|
with patch.object(handler2, 'send_response'):
|
|
with patch.object(handler2, 'end_headers'):
|
|
handler2.do_status() # Increments to 4
|
|
|
|
# Both handlers should see the same counter
|
|
# 2 handler creations + 2 do_status calls = 4
|
|
self.assertEqual(handler1.requests_served, 4)
|
|
self.assertEqual(handler2.requests_served, 4)
|
|
self.assertEqual(SimpleHTTPRequestHandler.requests_served, 4)
|
|
|
|
|
|
class TestServerModuleFunctions(unittest.TestCase):
|
|
|
|
def setUp(self):
|
|
"""
|
|
Set up test fixtures for server module functions
|
|
"""
|
|
server.server_status = ""
|
|
|
|
def test_publish_kraken_status_sets_server_status(self):
|
|
"""
|
|
Test publish_kraken_status sets global server_status
|
|
"""
|
|
server.publish_kraken_status("NEW_STATUS")
|
|
self.assertEqual(server.server_status, "NEW_STATUS")
|
|
|
|
def test_publish_kraken_status_overwrites_existing_status(self):
|
|
"""
|
|
Test publish_kraken_status overwrites existing status
|
|
"""
|
|
server.server_status = "OLD_STATUS"
|
|
server.publish_kraken_status("NEW_STATUS")
|
|
self.assertEqual(server.server_status, "NEW_STATUS")
|
|
|
|
@patch('server.HTTPServer')
|
|
@patch('server._thread')
|
|
def test_start_server_creates_http_server(self, mock_thread, mock_http_server):
|
|
"""
|
|
Test start_server creates HTTPServer with correct address
|
|
"""
|
|
address = ("localhost", 8080)
|
|
mock_server_instance = MagicMock()
|
|
mock_http_server.return_value = mock_server_instance
|
|
|
|
server.start_server(address, "RUNNING")
|
|
|
|
mock_http_server.assert_called_once_with(
|
|
address,
|
|
SimpleHTTPRequestHandler
|
|
)
|
|
|
|
@patch('server.HTTPServer')
|
|
@patch('server._thread')
|
|
def test_start_server_starts_thread(self, mock_thread, mock_http_server):
|
|
"""
|
|
Test start_server starts a new thread for serve_forever
|
|
"""
|
|
address = ("localhost", 8080)
|
|
mock_server_instance = MagicMock()
|
|
mock_http_server.return_value = mock_server_instance
|
|
|
|
server.start_server(address, "RUNNING")
|
|
|
|
mock_thread.start_new_thread.assert_called_once()
|
|
# Check that serve_forever was passed to the thread
|
|
args = mock_thread.start_new_thread.call_args[0]
|
|
self.assertEqual(args[0], mock_server_instance.serve_forever)
|
|
|
|
@patch('server.HTTPServer')
|
|
@patch('server._thread')
|
|
def test_start_server_publishes_status(self, mock_thread, mock_http_server):
|
|
"""
|
|
Test start_server publishes the provided status
|
|
"""
|
|
address = ("localhost", 8080)
|
|
mock_server_instance = MagicMock()
|
|
mock_http_server.return_value = mock_server_instance
|
|
|
|
server.start_server(address, "INITIAL_STATUS")
|
|
|
|
self.assertEqual(server.server_status, "INITIAL_STATUS")
|
|
|
|
@patch('server.HTTPConnection')
|
|
def test_get_status_makes_http_request(self, mock_http_connection):
|
|
"""
|
|
Test get_status makes HTTP GET request to root path
|
|
"""
|
|
address = ("localhost", 8080)
|
|
mock_connection = MagicMock()
|
|
mock_response = MagicMock()
|
|
mock_response.read.return_value = b"TEST_STATUS"
|
|
mock_connection.getresponse.return_value = mock_response
|
|
mock_http_connection.return_value = mock_connection
|
|
|
|
result = server.get_status(address)
|
|
|
|
mock_http_connection.assert_called_once_with("localhost", 8080)
|
|
mock_connection.request.assert_called_once_with("GET", "/")
|
|
self.assertEqual(result, "TEST_STATUS")
|
|
|
|
@patch('server.HTTPConnection')
|
|
def test_get_status_returns_decoded_response(self, mock_http_connection):
|
|
"""
|
|
Test get_status returns decoded response string
|
|
"""
|
|
address = ("localhost", 8080)
|
|
mock_connection = MagicMock()
|
|
mock_response = MagicMock()
|
|
mock_response.read.return_value = b"RUNNING"
|
|
mock_connection.getresponse.return_value = mock_response
|
|
mock_http_connection.return_value = mock_connection
|
|
|
|
result = server.get_status(address)
|
|
|
|
self.assertEqual(result, "RUNNING")
|
|
self.assertIsInstance(result, str)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|