diff options
Diffstat (limited to 'src/tests/input_common')
-rw-r--r-- | src/tests/input_common/calibration_configuration_job.cpp | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/src/tests/input_common/calibration_configuration_job.cpp b/src/tests/input_common/calibration_configuration_job.cpp new file mode 100644 index 000000000..8c77d81e9 --- /dev/null +++ b/src/tests/input_common/calibration_configuration_job.cpp @@ -0,0 +1,136 @@ +// Copyright 2020 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <array> +#include <string> +#include <thread> +#include <boost/asio.hpp> +#include <boost/crc.hpp> +#include <catch2/catch.hpp> + +#include "input_common/drivers/udp_client.h" +#include "input_common/helpers/udp_protocol.h" + +class FakeCemuhookServer { +public: + FakeCemuhookServer() + : socket(io_service, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 0)) {} + + ~FakeCemuhookServer() { + is_running = false; + boost::system::error_code error_code; + socket.shutdown(boost::asio::socket_base::shutdown_both, error_code); + socket.close(); + if (handler.joinable()) { + handler.join(); + } + } + + u16 GetPort() { + return socket.local_endpoint().port(); + } + + std::string GetHost() { + return socket.local_endpoint().address().to_string(); + } + + void Run(const std::vector<InputCommon::CemuhookUDP::Response::TouchPad> touch_movement_path) { + constexpr size_t HeaderSize = sizeof(InputCommon::CemuhookUDP::Header); + constexpr size_t PadDataSize = + sizeof(InputCommon::CemuhookUDP::Message<InputCommon::CemuhookUDP::Response::PadData>); + + REQUIRE(touch_movement_path.size() > 0); + is_running = true; + handler = std::thread([touch_movement_path, this]() { + auto current_touch_position = touch_movement_path.begin(); + while (is_running) { + boost::asio::ip::udp::endpoint sender_endpoint; + boost::system::error_code error_code; + auto received_size = socket.receive_from(boost::asio::buffer(receive_buffer), + sender_endpoint, 0, error_code); + + if (received_size < HeaderSize) { + continue; + } + + InputCommon::CemuhookUDP::Header header{}; + std::memcpy(&header, receive_buffer.data(), HeaderSize); + switch (header.type) { + case InputCommon::CemuhookUDP::Type::PadData: { + InputCommon::CemuhookUDP::Response::PadData pad_data{}; + pad_data.touch[0] = *current_touch_position; + const auto pad_message = InputCommon::CemuhookUDP::CreateMessage( + InputCommon::CemuhookUDP::SERVER_MAGIC, pad_data, 0); + std::memcpy(send_buffer.data(), &pad_message, PadDataSize); + socket.send_to(boost::asio::buffer(send_buffer, PadDataSize), sender_endpoint, + 0, error_code); + + bool can_advance = + std::next(current_touch_position) != touch_movement_path.end(); + if (can_advance) { + std::advance(current_touch_position, 1); + } + break; + } + case InputCommon::CemuhookUDP::Type::PortInfo: + case InputCommon::CemuhookUDP::Type::Version: + default: + break; + } + } + }); + } + +private: + boost::asio::io_service io_service; + boost::asio::ip::udp::socket socket; + std::array<u8, InputCommon::CemuhookUDP::MAX_PACKET_SIZE> send_buffer; + std::array<u8, InputCommon::CemuhookUDP::MAX_PACKET_SIZE> receive_buffer; + bool is_running = false; + std::thread handler; +}; + +TEST_CASE("CalibrationConfigurationJob completed", "[input_common]") { + Common::Event complete_event; + FakeCemuhookServer server; + server.Run({{ + .is_active = 1, + .x = 0, + .y = 0, + }, + { + .is_active = 1, + .x = 200, + .y = 200, + }}); + + InputCommon::CemuhookUDP::CalibrationConfigurationJob::Status status{}; + u16 min_x{}; + u16 min_y{}; + u16 max_x{}; + u16 max_y{}; + InputCommon::CemuhookUDP::CalibrationConfigurationJob job( + server.GetHost(), server.GetPort(), + [&status, + &complete_event](InputCommon::CemuhookUDP::CalibrationConfigurationJob::Status status_) { + status = status_; + if (status == + InputCommon::CemuhookUDP::CalibrationConfigurationJob::Status::Completed) { + complete_event.Set(); + } + }, + [&](u16 min_x_, u16 min_y_, u16 max_x_, u16 max_y_) { + min_x = min_x_; + min_y = min_y_; + max_x = max_x_; + max_y = max_y_; + }); + + complete_event.WaitUntil(std::chrono::system_clock::now() + std::chrono::seconds(10)); + REQUIRE(status == InputCommon::CemuhookUDP::CalibrationConfigurationJob::Status::Completed); + REQUIRE(min_x == 0); + REQUIRE(min_y == 0); + REQUIRE(max_x == 200); + REQUIRE(max_y == 200); +} |