From dc7a18d82eb0013a2afbdea9ba5fec131fc3179f Mon Sep 17 00:00:00 2001 From: Justin Berger Date: Sat, 22 Jul 2017 17:23:11 -0600 Subject: server: test buffer parsing --- CMakeLists.txt | 3 + Tests/CMakeLists.txt | 4 ++ Tests/CMakeServerLib/CMakeLists.txt | 17 ++++++ Tests/CMakeServerLib/testServerBuffering.cpp | 86 ++++++++++++++++++++++++++++ 4 files changed, 110 insertions(+) create mode 100644 Tests/CMakeServerLib/CMakeLists.txt create mode 100644 Tests/CMakeServerLib/testServerBuffering.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index c9e632e..c578ec3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -753,6 +753,9 @@ add_subdirectory(Tests) if(NOT CMake_TEST_EXTERNAL_CMAKE) if(BUILD_TESTING) CMAKE_SET_TARGET_FOLDER(CMakeLibTests "Tests") + IF(TARGET CMakeServerLibTests) + CMAKE_SET_TARGET_FOLDER(CMakeServerLibTests "Tests") + ENDIF() endif() if(TARGET documentation) CMAKE_SET_TARGET_FOLDER(documentation "Documentation") diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index f0e58ee..516bc89 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -146,6 +146,10 @@ if(BUILD_TESTING) if(NOT CMake_TEST_EXTERNAL_CMAKE) add_subdirectory(CMakeLib) + + if(CMake_TEST_SERVER_MODE) + add_subdirectory(CMakeServerLib) + endif() endif() add_subdirectory(CMakeOnly) add_subdirectory(RunCMake) diff --git a/Tests/CMakeServerLib/CMakeLists.txt b/Tests/CMakeServerLib/CMakeLists.txt new file mode 100644 index 0000000..f5351fd --- /dev/null +++ b/Tests/CMakeServerLib/CMakeLists.txt @@ -0,0 +1,17 @@ +include_directories( + ${CMAKE_CURRENT_BINARY_DIR} + ${CMake_BINARY_DIR}/Source + ${CMake_SOURCE_DIR}/Source + ) + +set(CMakeServerLib_TESTS + testServerBuffering + ) + +create_test_sourcelist(CMakeLib_TEST_SRCS CMakeServerLibTests.cxx ${CMakeServerLib_TESTS}) +add_executable(CMakeServerLibTests ${CMakeLib_TEST_SRCS}) +target_link_libraries(CMakeServerLibTests CMakeLib CMakeServerLib) + +foreach(test ${CMakeServerLib_TESTS}) + add_test(CMakeServerLib.${test} CMakeServerLibTests ${test} ${${test}_ARGS}) +endforeach() diff --git a/Tests/CMakeServerLib/testServerBuffering.cpp b/Tests/CMakeServerLib/testServerBuffering.cpp new file mode 100644 index 0000000..97be891 --- /dev/null +++ b/Tests/CMakeServerLib/testServerBuffering.cpp @@ -0,0 +1,86 @@ +#include "cmConnection.h" +#include "cmServerConnection.h" +#include +#include +#include +#include + +void print_error(const std::vector& input, + const std::vector& output) +{ + std::cerr << "Responses don't equal input messages input." << std::endl; + std::cerr << "Responses: " << std::endl; + + for (auto& msg : output) { + std::cerr << "'" << msg << "'" << std::endl; + } + + std::cerr << "Input messages" << std::endl; + for (auto& msg : input) { + std::cerr << "'" << msg << "'" << std::endl; + } +} + +std::string trim_newline(const std::string& _buffer) +{ + auto buffer = _buffer; + while (!buffer.empty() && (buffer.back() == '\n' || buffer.back() == '\r')) { + buffer.pop_back(); + } + return buffer; +} + +int testServerBuffering(int, char** const) +{ + std::vector messages = { + "{ \"test\": 10}", "{ \"test\": { \"test2\": false} }", + "{ \"test\": [1, 2, 3] }", + "{ \"a\": { \"1\": {}, \n\n\n \"2\":[] \t\t\t\t}}" + }; + + std::string fullMessage; + for (auto& msg : messages) { + fullMessage += "[== \"CMake Server\" ==[\n"; + fullMessage += msg; + fullMessage += "\n]== \"CMake Server\" ==]\n"; + } + + // The buffering strategy should cope with any fragmentation, including + // just getting the characters one at a time. + auto bufferingStrategy = + std::unique_ptr(new cmServerBufferStrategy); + std::vector response; + std::string rawBuffer; + for (size_t i = 0; i < fullMessage.size(); i++) { + rawBuffer += fullMessage[i]; + std::string packet = bufferingStrategy->BufferMessage(rawBuffer); + do { + if (!packet.empty() && packet != "\r\n") { + response.push_back(trim_newline(packet)); + } + packet = bufferingStrategy->BufferMessage(rawBuffer); + } while (!packet.empty()); + } + + if (response != messages) { + print_error(messages, response); + return 1; + } + + // We should also be able to deal with getting a bunch at once + response.clear(); + std::string packet = bufferingStrategy->BufferMessage(fullMessage); + do { + if (!packet.empty() && packet != "\r\n") { + response.push_back(trim_newline(packet)); + } + packet = bufferingStrategy->BufferMessage(fullMessage); + } while (!packet.empty()); + + if (response != messages) { + print_error(messages, response); + return 1; + } + + return 0; +} -- cgit v0.12