Add admin port support with other major refactorations
Some checks failed
Continuous Integration / lint-and-security (pull_request) Failing after 39s
Continuous Integration / tests-and-coverage (pull_request) Successful in 24s

This commit is contained in:
2026-06-29 19:47:48 +02:00
parent df629b2922
commit aebd5f4ef5
22 changed files with 1746 additions and 67 deletions

View File

@@ -8,18 +8,20 @@ We welcome contributions from the community! To maintain the high quality of thi
- **Minimal Dependencies:** Only add new dependencies if absolutely necessary.
## Testing Mandate
We enforce **100% test coverage**. Any new feature or bug fix must include corresponding tests.
We enforce **100% test coverage for normal (non-E2E) tests**. Any new feature or bug fix must include corresponding tests and maintain this coverage standard. E2E tests are only required to cover every public function with multiple inputs, and do not require 100% code coverage.
### Running Tests
Use `pytest` within the virtual environment:
For detailed testing instructions, please refer to the [Testing Guide](file:///home/kovagoadi/openttd-client/docs/TESTING.md).
Quick command to run normal (non-E2E) tests:
```bash
PYTHONPATH=lib ./venv/bin/pytest --cov=openttd --cov-report=term-missing tests/
./venv/bin/pytest -m "not e2e"
```
### Types of Tests
- **Logic Tests (`tests/test_logic.py`):** High-level client state and API behavior.
- **Protocol Tests (`tests/test_protocol.py`):** Low-level binary parsing and encryption.
- **E2E Tests (`tests/test_e2e.py`):** Integration tests against a live server.
Quick command to run all tests (including E2E):
```bash
./venv/bin/pytest
```
## Submitting Changes
1. **Fork the repo** and create your branch from `main`.

View File

@@ -15,6 +15,17 @@ We use **Blake2b** (64-byte digest) to derive two 32-byte session keys.
### Handshake Nonces
The server provides a 24-byte nonce in the `ServerAuthenticationRequest`. This nonce is used for the AEAD challenge during the auth response and for the initial stream encryption setup.
## Admin Network (TCP 3977)
The Admin Network allows external applications to monitor and control the server. It supports both unsecured and secure (X25519 PAKE) authentication.
### Secure Authentication
Similar to the Game Port, the Admin Network uses X25519 PAKE for secure authentication.
- **Packet:** `AdminJoinSecure` starts the handshake.
- **Encryption:** Once enabled via `ServerEnableEncryption`, all subsequent traffic is encrypted using XChaCha20-Poly1305.
### Update Frequencies
Admins can subscribe to various updates (Date, Client Info, Company Info, etc.) at different frequencies (Poll, Daily, Weekly, Monthly, Quarterly, Annually, Automatic).
## Stream Encryption (AEAD)
Once `ServerEnableEncryption` is received, all subsequent packets use **XChaCha20-Poly1305** (Authenticated Encryption with Associated Data).

104
docs/TESTING.md Normal file
View File

@@ -0,0 +1,104 @@
# Testing Guide for OpenTTD Python Client
This guide explains how the test suite is structured, the types of tests available, and how to execute them.
---
## 📂 Test Suite Structure
The tests are located in the `tests/` directory:
| Test File | Target | Description |
| :--- | :--- | :--- |
| [`test_admin.py`](file:///home/kovagoadi/openttd-client/tests/test_admin.py) | `OpenTTDAdminClient` | Tests admin client initialization, admin packet types, and basic protocol constants. |
| [`test_protocol.py`](file:///home/kovagoadi/openttd-client/tests/test_protocol.py) | `OpenTTDProtocol` | Tests binary serialization, custom parsers, and stream encryption/decryption (XChaCha20-Poly1305). |
| [`test_logic.py`](file:///home/kovagoadi/openttd-client/tests/test_logic.py) | `OpenTTDClient` | Tests client connection lifecycle, company joining flow, authentication, and state management. |
| [`test_coverage.py`](file:///home/kovagoadi/openttd-client/tests/test_coverage.py) | Coverage Helpers | Auxiliary unit tests targeting connection errors, fallback packet handlers, and missing passwords to ensure high test coverage. |
| [`test_e2e.py`](file:///home/kovagoadi/openttd-client/tests/test_e2e.py) | Integration / E2E | Connects to a running local OpenTTD server (e.g., in Docker) to verify full socket interactions, stream cryptography, and keep-alive frames. |
---
## 🚀 How to Run Tests
Pytest automatically uses [`pytest.ini`](file:///home/kovagoadi/openttd-client/pytest.ini) to configure the Python import path (`pythonpath = lib`). You do not need to manually configure `PYTHONPATH`.
Make sure your virtual environment is active before running commands:
```bash
source venv/bin/activate
```
### 1. Run Normal (Non-E2E) Tests
These are unit and logic tests that run instantly in memory without external dependencies:
```bash
pytest -m "not e2e"
```
### 2. Run E2E Tests Only
Requires a running local OpenTTD server configured with password `"asd"`. If the server is offline, this test will fail:
```bash
pytest -m "e2e"
```
---
## 🐳 Starting the OpenTTD Server (Docker)
To run E2E tests locally, you can start the dedicated JGRPP OpenTTD server using the provided Docker Compose configuration in the `docker/` directory.
### 1. Build and Start the Server
Run this command from the project root directory:
```bash
docker compose -f docker/docker-compose.yml up -d --build
```
*Note: The first build will clone and compile the JGRPP source code, which may take a few minutes.*
### 2. Monitor Server Logs
To watch the server logs (e.g., to see client connections and events):
```bash
docker compose -f docker/docker-compose.yml logs -f
```
### 3. Stop the Server
To stop the server container:
```bash
docker compose -f docker/docker-compose.yml down
```
### 3. Run All Tests
Runs both unit/logic tests and E2E tests:
```bash
pytest
```
### 4. Run with Coverage Report
To view statement coverage statistics:
```bash
pytest --cov=openttd --cov-report=term-missing
```
---
## 📊 Testing Mandate
We enforce the following testing mandates:
* **Normal/Unit tests (`pytest -m "not e2e"`)** must achieve 100% code coverage on the codebase independently.
* **E2E tests (`pytest -m "e2e"`)** do NOT require 100% code coverage. Instead, they are only required to cover every public function of the client classes (`OpenTTDClient` and `OpenTTDAdminClient`) and protocol classes with multiple (varied) inputs/scenarios.
To run/verify tests:
* **Normal Tests (Must achieve 100% coverage):**
```bash
pytest -m "not e2e" --cov=openttd --cov-report=term-missing --cov-fail-under=100
```
* **E2E Tests (No coverage mandate, must cover all public functions with multiple inputs):**
```bash
pytest -m "e2e"
```
---
## 🔧 Pytest Configuration (`pytest.ini`)
The project uses a [`pytest.ini`](file:///home/kovagoadi/openttd-client/pytest.ini) file at the root:
- **`pythonpath = lib`**: Simplifies invocation by resolving imports from the local `lib/` directory.
- **`markers`**: Registers the custom `e2e` marker for pytest classification.