Skip to content

Commit

Permalink
fix(tests): race condition in http server mock
Browse files Browse the repository at this point in the history
  • Loading branch information
memben committed Nov 20, 2024
1 parent 2451735 commit 8a60784
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 49 deletions.
30 changes: 24 additions & 6 deletions tests/mock_http_server.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
from __future__ import annotations

import json
from http.server import HTTPServer, BaseHTTPRequestHandler
import threading
import time
from urllib.parse import urlparse


Expand Down Expand Up @@ -176,12 +180,26 @@ def do_DELETE(self):
self.send_error(404, "Not Found")


def run_mock_server(port=8000):
server_address = ("", port)
httpd = HTTPServer(server_address, MockClaudeAIHandler)
print(f"Mock server running on port {port}")
httpd.serve_forever()
class SharedMockServer:
_instance: SharedMockServer | None = None
_server: HTTPServer | None = None
_thread: threading.Thread | None = None

@classmethod
def get_instance(cls):
if cls._instance is None:
cls._instance = cls()
return cls._instance

def start(self):
if self._server is None:
self._server = HTTPServer(("", 8000), MockClaudeAIHandler)
self._thread = threading.Thread(target=self._server.serve_forever)
self._thread.daemon = True
self._thread.start()
time.sleep(1) # Give the server a moment to start


if __name__ == "__main__":
run_mock_server()
server = SharedMockServer.get_instance()
server.start()
15 changes: 15 additions & 0 deletions tests/test_base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import unittest

from claudesync.configmanager.inmemory_config_manager import InMemoryConfigManager
from tests.mock_http_server import SharedMockServer


class BaseTestCase(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.mock_server = SharedMockServer.get_instance()
cls.mock_server.start()

def setUp(self):
self.config = InMemoryConfigManager()
self.config.set("claude_api_url", "http://localhost:8000/api")
17 changes: 5 additions & 12 deletions tests/test_chat_happy_path.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,18 @@
from typing import override
import unittest
import threading
import time
from click.testing import CliRunner
from claudesync.cli.main import cli
from claudesync.configmanager import InMemoryConfigManager
from mock_http_server import run_mock_server
from tests.test_base import BaseTestCase


class TestChatHappyPath(unittest.TestCase):
@classmethod
def setUpClass(cls):
# Start the mock server in a separate thread
cls.mock_server_thread = threading.Thread(target=run_mock_server)
cls.mock_server_thread.daemon = True
cls.mock_server_thread.start()
time.sleep(1) # Give the server a moment to start

class TestChatHappyPath(BaseTestCase):
@override
def setUp(self):
super().setUp()
self.runner = CliRunner()
self.config = InMemoryConfigManager()
self.config.set("claude_api_url", "http://localhost:8000/api")

def test_chat_happy_path(self):
# Step 1: Login
Expand Down
19 changes: 5 additions & 14 deletions tests/test_claude_ai.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,17 @@
from typing import override
import unittest
import threading
import time
from unittest.mock import patch
from datetime import datetime

from claudesync.configmanager import InMemoryConfigManager
from claudesync.providers.claude_ai import ClaudeAIProvider
from claudesync.exceptions import ProviderError
from mock_http_server import run_mock_server
from tests.test_base import BaseTestCase


class TestClaudeAIProvider(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.mock_server_thread = threading.Thread(target=run_mock_server)
cls.mock_server_thread.daemon = True
cls.mock_server_thread.start()
time.sleep(1)

class TestClaudeAIProvider(BaseTestCase):
@override
def setUp(self):
self.config = InMemoryConfigManager()
self.config.set("claude_api_url", "http://127.0.0.1:8000/api")
super().setUp()
self.provider = ClaudeAIProvider(self.config)

def test_get_organizations(self):
Expand Down
22 changes: 5 additions & 17 deletions tests/test_happy_path.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,16 @@
import threading
import time
from typing import override
import unittest
from click.testing import CliRunner
from unittest.mock import patch
from claudesync.cli.main import cli
from claudesync.configmanager import InMemoryConfigManager
from mock_http_server import run_mock_server
from tests.test_base import BaseTestCase


class TestClaudeSyncHappyPath(unittest.TestCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.mock_server_thread = threading.Thread(target=run_mock_server)
cls.mock_server_thread.daemon = True
cls.mock_server_thread.start()
time.sleep(1) # Wait for the mock server to start

class TestClaudeSyncHappyPath(BaseTestCase):
@override
def setUp(self):
super().setUp()
self.runner = CliRunner()
self.config = InMemoryConfigManager()
self.config.set(
"claude_api_url", "http://127.0.0.1:8000/api"
) # Set BASE_URL for the mock server

@patch("claudesync.utils.get_local_files")
def test_happy_path(self, mock_get_local_files):
Expand Down

0 comments on commit 8a60784

Please sign in to comment.