diff --git a/3d_party/rapidjson/include/rapidjson/reader.h b/3d_party/rapidjson/include/rapidjson/reader.h index 9b28b268530ca29101b4e351fd4228899a223e4e..206b261417b9bc15594fec165685339123b639c0 100644 --- a/3d_party/rapidjson/include/rapidjson/reader.h +++ b/3d_party/rapidjson/include/rapidjson/reader.h @@ -1223,7 +1223,8 @@ class GenericReader { } i = i * 10 + static_cast<unsigned>(s.TakePush() - '0'); significandDigit++; - } else + } + else while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { if (RAPIDJSON_UNLIKELY(i >= 429496729)) { // 2^32 - 1 = 4294967295 if (RAPIDJSON_LIKELY(i != 429496729 || s.Peek() > '5')) { @@ -1264,7 +1265,8 @@ class GenericReader { } i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0'); significandDigit++; - } else + } + else while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x19999999, 0x99999999))) // 2^64 - 1 = 18446744073709551615 if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || s.Peek() > '5')) { diff --git a/common/cpp/include/common/error.h b/common/cpp/include/common/error.h index d3245c683af7409c383952668272d724a2e8e650..eae83b33b75d622820f9079ae5d226a6783a093f 100644 --- a/common/cpp/include/common/error.h +++ b/common/cpp/include/common/error.h @@ -145,11 +145,11 @@ inline Error TextErrorWithType(const std::string& error, ErrorType error_type) { namespace ErrorTemplates { auto const kMemoryAllocationError = SimpleErrorTemplate { - "kMemoryAllocationError", ErrorType::kMemoryAllocationError - }; + "kMemoryAllocationError", ErrorType::kMemoryAllocationError +}; auto const kEndOfFile = SimpleErrorTemplate { - "End of file", ErrorType::kEndOfFile - }; + "End of file", ErrorType::kEndOfFile +}; } diff --git a/common/cpp/include/system_wrappers/io.h b/common/cpp/include/system_wrappers/io.h index c10e3591d52eef0f26b9ef42c9d9255cbd9fb69f..41e626caaecef0b6316266cf1c5fd759399be7d1 100644 --- a/common/cpp/include/system_wrappers/io.h +++ b/common/cpp/include/system_wrappers/io.h @@ -79,64 +79,64 @@ static inline std::ostream& operator<<(std::ostream& os, const IOErrorTemplate& namespace IOErrorTemplates { auto const kUnknownIOError = IOErrorTemplate { - "Unknown Error", IOErrorType::kUnknownIOError - }; + "Unknown Error", IOErrorType::kUnknownIOError +}; auto const kFileNotFound = IOErrorTemplate { - "No such file or directory", IOErrorType::kFileNotFound - }; + "No such file or directory", IOErrorType::kFileNotFound +}; auto const kReadError = IOErrorTemplate { - "Read error", IOErrorType::kReadError - }; + "Read error", IOErrorType::kReadError +}; auto const kBadFileNumber = IOErrorTemplate { - "Bad file number", IOErrorType::kBadFileNumber - }; + "Bad file number", IOErrorType::kBadFileNumber +}; auto const kResourceTemporarilyUnavailable = IOErrorTemplate { - "Resource temporarily unavailable", IOErrorType::kResourceTemporarilyUnavailable - }; + "Resource temporarily unavailable", IOErrorType::kResourceTemporarilyUnavailable +}; auto const kPermissionDenied = IOErrorTemplate { - "Permission denied", IOErrorType::kPermissionDenied - }; + "Permission denied", IOErrorType::kPermissionDenied +}; auto const kUnsupportedAddressFamily = IOErrorTemplate { - "Unsupported address family", IOErrorType::kUnsupportedAddressFamily - }; + "Unsupported address family", IOErrorType::kUnsupportedAddressFamily +}; auto const kInvalidAddressFormat = IOErrorTemplate { - "Invalid address format", IOErrorType::kInvalidAddressFormat - }; + "Invalid address format", IOErrorType::kInvalidAddressFormat +}; auto const kAddressAlreadyInUse = IOErrorTemplate { - "Address already in use", IOErrorType::kAddressAlreadyInUse - }; + "Address already in use", IOErrorType::kAddressAlreadyInUse +}; auto const kConnectionRefused = IOErrorTemplate { - "Connection refused", IOErrorType::kConnectionRefused - }; + "Connection refused", IOErrorType::kConnectionRefused +}; auto const kConnectionResetByPeer = IOErrorTemplate { - "kConnectionResetByPeer", IOErrorType::kConnectionResetByPeer - }; + "kConnectionResetByPeer", IOErrorType::kConnectionResetByPeer +}; auto const kTimeout = IOErrorTemplate { - "kTimeout", IOErrorType::kTimeout - }; + "kTimeout", IOErrorType::kTimeout +}; auto const kFileAlreadyExists = IOErrorTemplate { - "kFileAlreadyExists", IOErrorType::kFileAlreadyExists - }; + "kFileAlreadyExists", IOErrorType::kFileAlreadyExists +}; auto const kNoSpaceLeft = IOErrorTemplate { - "kNoSpaceLeft", IOErrorType::kNoSpaceLeft - }; + "kNoSpaceLeft", IOErrorType::kNoSpaceLeft +}; auto const kSocketOperationOnNonSocket = IOErrorTemplate { - "kSocketOperationOnNonSocket", IOErrorType::kSocketOperationOnNonSocket - }; + "kSocketOperationOnNonSocket", IOErrorType::kSocketOperationOnNonSocket +}; auto const kInvalidMemoryAddress = IOErrorTemplate { - "kInvalidMemoryAddress", IOErrorType::kInvalidMemoryAddress - }; + "kInvalidMemoryAddress", IOErrorType::kInvalidMemoryAddress +}; auto const kUnableToResolveHostname = IOErrorTemplate { - "kUnableToResolveHostname", IOErrorType::kUnableToResolveHostname - }; + "kUnableToResolveHostname", IOErrorType::kUnableToResolveHostname +}; auto const kSocketOperationUnknownAtLevel = IOErrorTemplate { - "kSocketOperationUnknownAtLevel", IOErrorType::kSocketOperationUnknownAtLevel - }; + "kSocketOperationUnknownAtLevel", IOErrorType::kSocketOperationUnknownAtLevel +}; auto const kSocketOperationValueOutOfBound = IOErrorTemplate { - "kSocketOperationValueOutOfBound", IOErrorType::kSocketOperationValueOutOfBound - }; + "kSocketOperationValueOutOfBound", IOErrorType::kSocketOperationValueOutOfBound +}; } diff --git a/common/cpp/src/system_io/system_io_windows.cpp b/common/cpp/src/system_io/system_io_windows.cpp index 483956f00899ca7d352fffd78934dc5c5293082d..796a3b1832b566276e1201f68a0e5ae19c47a785 100644 --- a/common/cpp/src/system_io/system_io_windows.cpp +++ b/common/cpp/src/system_io/system_io_windows.cpp @@ -38,10 +38,12 @@ Error IOErrorFromGetLastError() { return IOErrorTemplates::kResourceTemporarilyUnavailable.Generate(); case WSAECONNREFUSED: return IOErrorTemplates::kConnectionRefused.Generate(); + case ERROR_FILE_EXISTS: + return IOErrorTemplates::kFileAlreadyExists.Generate(); default: std::cout << "[IOErrorFromGetLastError] Unknown error code: " << last_error << std::endl; Error err = IOErrorTemplates::kUnknownIOError.Generate(); - (*err).Append("Unknown error code: " + std::to_string(errno)); + (*err).Append("Unknown error code: " + std::to_string(last_error)); return err; } } diff --git a/receiver/src/receiver_error.h b/receiver/src/receiver_error.h index 63da34f6fe47518ca7d55278a47e82b0f302d7ed..42eb039d8e5720e23a98dfded74973b788233235 100644 --- a/receiver/src/receiver_error.h +++ b/receiver/src/receiver_error.h @@ -50,11 +50,11 @@ class ReceiverErrorTemplate : public SimpleErrorTemplate { namespace ReceiverErrorTemplates { auto const kInvalidOpCode = ReceiverErrorTemplate { - "Invalid Opcode", ReceiverErrorType::kInvalidOpCode - }; + "Invalid Opcode", ReceiverErrorType::kInvalidOpCode +}; auto const kBadRequest = ReceiverErrorTemplate { - "Bad request", ReceiverErrorType::kBadRequest - }; + "Bad request", ReceiverErrorType::kBadRequest +}; }; } diff --git a/receiver/src/request_handler_file_write.cpp b/receiver/src/request_handler_file_write.cpp index 2796f6321f0f4561f35fab2ccdad7382eed52d23..6321db31f6d62559ae2ad87148752e8d7a2d4569 100644 --- a/receiver/src/request_handler_file_write.cpp +++ b/receiver/src/request_handler_file_write.cpp @@ -12,7 +12,7 @@ Error RequestHandlerFileWrite::ProcessRequest(const Request& request) const { const FileData& data = request.GetData(); auto fname = request.GetFileName(); - +//TODO: folder to write in config file return io__->WriteDataToFile("files/" + fname, data, fsize); } diff --git a/receiver/unittests/test_request.cpp b/receiver/unittests/test_request.cpp index 7e6f175f796ce927bb8b5e46f95e86523f6c81be..9b263826fe308534afd922688f6a64cf2311619e 100644 --- a/receiver/unittests/test_request.cpp +++ b/receiver/unittests/test_request.cpp @@ -79,10 +79,12 @@ class RequestTests : public Test { GenericNetworkRequestHeader generic_request_header; hidra2::SocketDescriptor socket_fd_{1}; uint64_t data_size_ {100}; + uint64_t data_id_{15}; std::unique_ptr<Request> request; NiceMock<MockIO> mock_io; void SetUp() override { generic_request_header.data_size = data_size_; + generic_request_header.data_id = data_id_; request.reset(new Request{generic_request_header, socket_fd_}); request->io__ = std::unique_ptr<hidra2::IO> {&mock_io}; ON_CALL(mock_io, Receive_t(socket_fd_, _, data_size_, _)).WillByDefault( @@ -138,5 +140,36 @@ TEST_F(RequestTests, HandleProcessesRequests) { ASSERT_THAT(err, Eq(hidra2::IOErrorTemplates::kUnknownIOError)); } +TEST_F(RequestTests, DataIsNullAtInit) { + auto& data = request->GetData(); + + ASSERT_THAT(data, Eq(nullptr)); +} + +TEST_F(RequestTests, GetDataIsNotNullptr) { + + request->Handle(); + auto& data = request->GetData(); + + + ASSERT_THAT(data, Ne(nullptr)); + + +} + + +TEST_F(RequestTests, GetDataSize) { + auto size = request->GetDataSize(); + + ASSERT_THAT(size, Eq(data_size_)); +} + +TEST_F(RequestTests, GetFileName) { + auto fname = request->GetFileName(); + auto s = std::to_string(data_id_) + ".bin"; + + ASSERT_THAT(fname, Eq(s)); +} + } diff --git a/receiver/unittests/test_request_handler_file_write.cpp b/receiver/unittests/test_request_handler_file_write.cpp index d330b855c31be28bbf9bbe787ce27241309e47e3..7c3dc1d09a1f0cc8396cd961e1c5ac7de93a986d 100644 --- a/receiver/unittests/test_request_handler_file_write.cpp +++ b/receiver/unittests/test_request_handler_file_write.cpp @@ -99,15 +99,14 @@ TEST_F(FileWriteHandlerTests, CallsWriteFile) { ; - EXPECT_CALL(mock_io, WriteDataToFile_t("files/"+expected_file_name, _, expected_file_size)) + EXPECT_CALL(mock_io, WriteDataToFile_t("files/" + expected_file_name, _, expected_file_size)) .WillOnce( - //Return(hidra2::IOErrorTemplates::kUnknownIOError.Generate().release()) - Return(nullptr) + Return(hidra2::IOErrorTemplates::kUnknownIOError.Generate().release()) ); auto err = handler.ProcessRequest(*mock_request); - ASSERT_THAT(err, Eq(nullptr)); + ASSERT_THAT(err, Eq(hidra2::IOErrorTemplates::kUnknownIOError)); } diff --git a/tests/system_io/CMakeLists.txt b/tests/system_io/CMakeLists.txt index 756bb90d64086a9a6c7f7a1807a86c6510680e31..84f9db59c371ee52ea4dc29e0a56f25e18a6cba2 100644 --- a/tests/system_io/CMakeLists.txt +++ b/tests/system_io/CMakeLists.txt @@ -5,3 +5,4 @@ add_subdirectory(read_file_content) add_subdirectory(read_string_from_file) add_subdirectory(ip_tcp_network) add_subdirectory(resolve_hostname_to_ip) +add_subdirectory(write_data_to_file) diff --git a/tests/system_io/write_data_to_file/CMakeLists.txt b/tests/system_io/write_data_to_file/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..fd034a4d2385b6b8069962b68ffc0485dd16afaa --- /dev/null +++ b/tests/system_io/write_data_to_file/CMakeLists.txt @@ -0,0 +1,20 @@ +set(TARGET_NAME write_data_to_file) +set(SOURCE_FILES write_data_to_file.cpp) + + +################################ +# Executable and link +################################ +add_executable(${TARGET_NAME} ${SOURCE_FILES} $<TARGET_OBJECTS:system_io> ) +target_link_libraries(${TARGET_NAME} test_common) +target_include_directories(${TARGET_NAME} PUBLIC ${CMAKE_SOURCE_DIR}/common/cpp/include) +set_target_properties(${TARGET_NAME} PROPERTIES LINKER_LANGUAGE CXX) + +################################ +# Testing +################################ +add_test_setup_cleanup(${TARGET_NAME}) +add_integration_test(${TARGET_NAME} writeok "test_file ok dummy" nomem) +add_integration_test(${TARGET_NAME} writetwice "test_file error kFileAlreadyExists:test" nomem) +add_integration_test(${TARGET_NAME} dirnoaccess "test_noaccess/test_file error Permissiondenied:test_noaccess/test_file" nomem) + diff --git a/tests/system_io/write_data_to_file/cleanup_linux.sh b/tests/system_io/write_data_to_file/cleanup_linux.sh new file mode 100644 index 0000000000000000000000000000000000000000..1a50a82324730dc9630f63142d6328926b2ca9f4 --- /dev/null +++ b/tests/system_io/write_data_to_file/cleanup_linux.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +rm -f test_file +rmdir test_noaccess + diff --git a/tests/system_io/write_data_to_file/cleanup_windows.bat b/tests/system_io/write_data_to_file/cleanup_windows.bat new file mode 100644 index 0000000000000000000000000000000000000000..256da63ada32b6f56a0273cc6ea378675be066cf --- /dev/null +++ b/tests/system_io/write_data_to_file/cleanup_windows.bat @@ -0,0 +1,4 @@ +del test_file + +icacls test_noaccess /grant:r users:W +rmdir /S /Q test_noaccess diff --git a/tests/system_io/write_data_to_file/setup_linux.sh b/tests/system_io/write_data_to_file/setup_linux.sh new file mode 100644 index 0000000000000000000000000000000000000000..63356273ee156761c7bcbcf4a9524d32cf134416 --- /dev/null +++ b/tests/system_io/write_data_to_file/setup_linux.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +mkdir test_noaccess +chmod -rx test_noaccess + diff --git a/tests/system_io/write_data_to_file/setup_windows.bat b/tests/system_io/write_data_to_file/setup_windows.bat new file mode 100644 index 0000000000000000000000000000000000000000..bc36d4ed8d9c3ac8e998f8ea7970ce8e1b1bb89d --- /dev/null +++ b/tests/system_io/write_data_to_file/setup_windows.bat @@ -0,0 +1,5 @@ +mkdir test_noaccess +icacls test_noaccess /deny users:W + + + diff --git a/tests/system_io/write_data_to_file/write_data_to_file.cpp b/tests/system_io/write_data_to_file/write_data_to_file.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2cb4a6d31242c2a5f48c1405e674bc011ff0100d --- /dev/null +++ b/tests/system_io/write_data_to_file/write_data_to_file.cpp @@ -0,0 +1,65 @@ +#include <iostream> +#include <system_wrappers/system_io.h> + +#include "testing.h" + +using hidra2::SystemIO; +using hidra2::Error; +using hidra2::FileData; + + +struct Params { + std::string fname; + std::string result; + std::string message; + int length; +}; + +Params GetParams(int argc, char* argv[]) { + if (argc != 4) { + std::cout << "Wrong number of arguments" << std::endl; + exit(EXIT_FAILURE); + } + std::string fname{argv[1]}; + std::string result{argv[2]}; + std::string message{argv[3]}; + + return Params{fname, result, message,3}; +} + +void AssertGoodResult(const std::unique_ptr<SystemIO>& io, const Error& err, const FileData& data, + const Params& params) { + if (err) { + std::cerr << err << std::endl; + exit(EXIT_FAILURE); + } + Error read_err; + auto read_data = io->GetDataFromFile(params.fname, params.length, &read_err); + hidra2::M_AssertContains(std::string(read_data.get(), read_data.get() + params.length), "123"); +} + +void AssertBadResult(const Error& err, const Params& params) { + if (err == nullptr) { + std::cerr << "Should be error" << std::endl; + exit(EXIT_FAILURE); + } + hidra2::M_AssertContains(err->Explain(), params.message); +} + + +int main(int argc, char* argv[]) { + auto params = GetParams(argc, argv); + + auto io = std::unique_ptr<SystemIO> {new SystemIO}; + FileData data{new uint8_t[params.length]{'1', '2', '3'}}; + + auto err = io->WriteDataToFile(params.fname, data, params.length); + + if (params.result == "ok") { + AssertGoodResult(io, err, data, params); + } else { + AssertBadResult(err, params); + } + + return 0; +}