API Server Unit Tests
Relevant source files
The following files were used as context for generating this wiki page:
The API Server Unit Tests ensure the reliability and compatibility of the Minecraft: Pi Edition protocol reconstruction. The testing suite focuses on two primary areas: the low-level parsing of MCPI-style commands and the high-level integration of the TCP server handling these commands. These tests are essential for Phase 1 of the project, which aims to preserve compatibility with the original programming API on port 4711.
The suite utilizes a combination of unit tests for the protocol parser and integration tests that spin up a local TCP server to simulate real-world client-server interactions. This approach validates that the mcpi::api::ApiServer correctly manages socket lifetimes, multi-threaded client handling, and command execution via provided handlers.
Sources: README.md:9-16, tests/api_server_tests.cpp:100-128, CMakeLists.txt:41-55
Test Architecture and Infrastructure
The project uses CMake to manage the build and execution of tests. When the MCPI_BUILD_TESTS option is enabled, two distinct executables are generated: mcpi_protocol_tests and mcpi_api_server_tests. These are integrated into the ctest harness for automated execution.
Sources: CMakeLists.txt:10-10, CMakeLists.txt:41-55
Core Test Components
| Component | Description | Source File |
|---|---|---|
mcpi_protocol_tests | Validates the parse_command logic for various MCPI string formats. | tests/protocol_tests.cpp |
mcpi_api_server_tests | Performs end-to-end TCP loopback testing using the ApiServer class. | tests/api_server_tests.cpp |
expect() | A helper function used across test files to assert conditions and exit on failure. | tests/api_server_tests.cpp:27-32] |
connect_loopback() | A platform-agnostic helper to establish a TCP connection for testing. | tests/api_server_tests.cpp:44-59] |
Protocol Parser Testing
The protocol tests focus on the mcpi::api::parse_command function, which converts raw strings into Command structures. The tests cover successful parsing, argument extraction, and rejection of malformed inputs.
Sources: tests/protocol_tests.cpp:18-45, src/api/Command.hpp:12-15
The diagram shows the logic flow within the command parser as validated by the unit tests.
Sources: src/api/Command.cpp:23-61
Test Cases for Parser
The protocol_tests.cpp file validates the following scenarios:
- Standard Commands:
world.setBlock(1,2,3,57)ensures multiple arguments are parsed and the last argument is preserved. - Zero-Argument Commands:
player.getPos()verifies that empty parentheses result in an empty arguments vector. - Space-Containing Arguments:
chat.post(Hello from Pi)ensures that spaces within the command body are correctly handled as a single argument. - Rejection: Verifies that empty strings, strings without parentheses, or strings with trailing data (e.g.,
world.setBlock(...) trailing) are rejected.
Sources: tests/protocol_tests.cpp:20-43
API Server Integration Testing
The mcpi_api_server_tests.cpp file provides a functional test of the ApiServer class. It initializes a server on an ephemeral port (port 0), registers a mock handler, and uses a native socket client to send commands and receive responses.
Sources: tests/api_server_tests.cpp:100-112
Client-Server Sequence
The following sequence diagram illustrates the interaction between the test client and the API server during the integration test:
This diagram shows the full lifecycle of a command during the integration test.
Sources: tests/api_server_tests.cpp:106-121, src/api/ApiServer.cpp:108-140
Key Implementation Details Tested
- Ephemeral Port Selection: Setting the port to
0in the constructor and verifyingserver.port()returns a non-zero system-assigned port. Sources: tests/api_server_tests.cpp:106-114, src/api/ApiServer.cpp:220-234 - Line-Based Communication: The server reads until
\nand the client expects a response ending in a newline. Sources: tests/api_server_tests.cpp:83-96, src/api/ApiServer.cpp:129-140 - Graceful Shutdown: Calling
server.stop()joins the worker thread and closes the listener socket. Sources: tests/api_server_tests.cpp:123-125, src/api/ApiServer.cpp:253-272
Platform Compatibility in Tests
Because the project supports modern Linux and Windows (x86-64), the test suite contains significant platform-specific socket code wrapped in macros.
Sources: README.md:12-13, tests/api_server_tests.cpp:10-25
// tests/api_server_tests.cpp:10-25
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <ws2tcpip.h>
using TestSocket = SOCKET;
constexpr TestSocket kInvalidSocket = INVALID_SOCKET;
#else
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>
using TestSocket = int;
constexpr TestSocket kInvalidSocket = -1;
#endif
This abstraction allows the test suite to validate the ApiServer implementation across different operating systems.
Sources: tests/api_server_tests.cpp:10-25, CMakeLists.txt:33-35
Conclusion
The API Server Unit Tests provide a robust foundation for verifying Phase 1 goals of Minecraft: Pi Edition protocol parity. By separating protocol parsing from network handling, the suite ensures that both the data format and the transmission mechanism are correctly reconstructed for modern systems.