diff --git a/broker/src/hidra2_broker/database/mongodb.go b/broker/src/hidra2_broker/database/mongodb.go index 4c76cb3f9c69a9890716c74fb51c5912c65053b7..c6e54099ea00a7eb53f0ba1f1ea3e6bc97368a40 100644 --- a/broker/src/hidra2_broker/database/mongodb.go +++ b/broker/src/hidra2_broker/database/mongodb.go @@ -54,7 +54,7 @@ func (db *Mongodb) dataBaseExist(dbname string) (err error) { } if !db.databaseInList(dbname) { - return errors.New("database not found: " + dbname) + return errors.New("dataset not found: " + dbname) } return nil diff --git a/common/cpp/CMakeLists.txt b/common/cpp/CMakeLists.txt index 288ffe42cafe4dfd30f188059f397715870dd2ba..7865db18df7b3087b583afa1c1a7077664afcf0b 100644 --- a/common/cpp/CMakeLists.txt +++ b/common/cpp/CMakeLists.txt @@ -2,7 +2,6 @@ add_subdirectory(src/system_io) add_subdirectory(src/data_structs) - if(BUILD_MONGODB_CLIENTLIB) add_subdirectory(src/database) endif() diff --git a/common/cpp/include/common/error.h b/common/cpp/include/common/error.h index 080ece57717c1f764b66394e5e8954b43d23ac32..8ef74d4f5963df36225a46efa25515cdf870129f 100644 --- a/common/cpp/include/common/error.h +++ b/common/cpp/include/common/error.h @@ -6,10 +6,17 @@ namespace hidra2 { +enum class ErrorType { + kHidraError, + kEOF, + kHttpError +}; + class ErrorInterface { public: virtual std::string Explain() const noexcept = 0; - virtual void Set(const std::string& error) noexcept = 0; + virtual void Append(const std::string& value) noexcept = 0; + virtual ErrorType GetErrorType() noexcept = 0; virtual ~ErrorInterface() = default; // needed for unique_ptr to delete itself }; @@ -19,15 +26,23 @@ using Error = std::unique_ptr<ErrorInterface>; class SimpleError: public ErrorInterface { private: std::string error_; + ErrorType error_type_ = ErrorType::kHidraError; public: explicit SimpleError(const std::string& error): error_{error} { } + SimpleError(const std::string& error, ErrorType error_type ): error_{error}, error_type_{error_type} { + } + + void Append(const std::string& value) noexcept override { + error_ += ": " + value; + } + std::string Explain() const noexcept override { return error_; } - void Set(const std::string& error)noexcept override { - error_ = error; + ErrorType GetErrorType()noexcept override { + return error_type_; } }; @@ -36,5 +51,10 @@ inline Error TextError(const std::string& error) { return Error{new SimpleError{error}}; } +inline Error TextErrorWithType(const std::string& error, ErrorType error_type) { + return Error{new SimpleError{error, error_type}}; +} + + } #endif //HIDRA2_ERROR_H diff --git a/common/cpp/include/system_wrappers/io.h b/common/cpp/include/system_wrappers/io.h index 9b73e407aa9063c8d09dc2ec042c4fc50b753df6..3f955b22943297c3a88e58b30a63c150e8b896c3 100644 --- a/common/cpp/include/system_wrappers/io.h +++ b/common/cpp/include/system_wrappers/io.h @@ -13,7 +13,7 @@ namespace hidra2 { namespace IOErrors { -auto const kFileNotFound = "File not found"; +auto const kFileNotFound = "No such file or directory"; auto const kReadError = "Read error"; auto const kPermissionDenied = "Permission denied"; auto const kUnknownError = "Unknown error"; diff --git a/common/cpp/src/system_io/system_io.cpp b/common/cpp/src/system_io/system_io.cpp index 0339443e2ed6fe68086d6df2e432f3684cde1a10..42a9f8b5c17b81b90513a8aef11cbe1f73d2a224 100644 --- a/common/cpp/src/system_io/system_io.cpp +++ b/common/cpp/src/system_io/system_io.cpp @@ -47,6 +47,7 @@ FileData SystemIO::GetDataFromFile(const std::string& fname, uint64_t fsize, Err int fd = open(fname.c_str(), O_RDONLY); *err = IOErrorFromErrno(); if (*err != nullptr) { + (*err)->Append(fname); return nullptr; } uint8_t* data_array = nullptr; @@ -61,6 +62,7 @@ FileData SystemIO::GetDataFromFile(const std::string& fname, uint64_t fsize, Err FileData data{data_array}; if (*err != nullptr) { close(fd); + (*err)->Append(fname); return nullptr; } errno = 0; diff --git a/common/cpp/src/system_io/system_io_linux.cpp b/common/cpp/src/system_io/system_io_linux.cpp index abee2bf59c1d5cb022fb5982f0405f901791d209..36adc6d3d394a9fe06fcf633fa7fe35bb1e75c2b 100644 --- a/common/cpp/src/system_io/system_io_linux.cpp +++ b/common/cpp/src/system_io/system_io_linux.cpp @@ -94,6 +94,7 @@ void SystemIO::CollectFileInformationRecursivly(const std::string& path, auto dir = opendir((path).c_str()); if (dir == nullptr) { *err = IOErrorFromErrno(); + (*err)->Append(path); return; } while (true) { diff --git a/common/cpp/src/system_io/system_io_windows.cpp b/common/cpp/src/system_io/system_io_windows.cpp index d4816ef18d8359109a02543bccaab442f4abf374..1a976f8a4ff1bbeea347f449e2d23972ef477100 100644 --- a/common/cpp/src/system_io/system_io_windows.cpp +++ b/common/cpp/src/system_io/system_io_windows.cpp @@ -108,6 +108,7 @@ void SystemIO::CollectFileInformationRecursivly(const std::string& path, HANDLE handle = FindFirstFile((path + "\\*.*").c_str(), &find_data); if (handle == INVALID_HANDLE_VALUE) { *err = IOErrorFromGetLastError(); + (*err)->Append(path); return; } diff --git a/examples/worker/getnext_broker/getnext_broker.cpp b/examples/worker/getnext_broker/getnext_broker.cpp index 20237acb8510bfe218350fbf91b5a612f74d09fc..0f578333b51ffb444c7ca0204a9d11e87883c66c 100644 --- a/examples/worker/getnext_broker/getnext_broker.cpp +++ b/examples/worker/getnext_broker/getnext_broker.cpp @@ -18,15 +18,24 @@ void WaitThreads(std::vector<std::thread>* threads) { } } +void ProcessError(const Error& err) { + if (err == nullptr) return; + if (err->GetErrorType() != hidra2::ErrorType::kEOF) { + std::cout << err->Explain() << std::endl; + exit(EXIT_FAILURE); + } +} + std::vector<std::thread> StartThreads(const std::string& server, const std::string& run_name, int nthreads, std::vector<int>* nfiles) { auto exec_next = [server, run_name, nfiles](int i) { hidra2::FileInfo fi; Error err; auto broker = hidra2::DataBrokerFactory::CreateServerBroker(server, run_name, &err); - while (broker->GetNext(&fi, nullptr) == nullptr) { + while ((err = broker->GetNext(&fi, nullptr)) == nullptr) { (*nfiles)[i] ++; } + ProcessError(err); }; std::vector<std::thread> threads; diff --git a/examples/worker/process_folder/process_folder.cpp b/examples/worker/process_folder/process_folder.cpp index da04b67c802c98dbc5d188677a9f3ecb30130049..fd789d2fdf1df19cde1564c4b7fe85f03669e286 100644 --- a/examples/worker/process_folder/process_folder.cpp +++ b/examples/worker/process_folder/process_folder.cpp @@ -41,7 +41,7 @@ void ConnectToBrocker(std::unique_ptr<hidra2::DataBroker>* broker, Statistics* s high_resolution_clock::time_point t1 = high_resolution_clock::now(); Error err = (*broker)->Connect(); if (err != nullptr) { - std::cout << "Cannot connect to broker" << std::endl; + std::cout << err->Explain() << std::endl; exit(EXIT_FAILURE); } high_resolution_clock::time_point t2 = high_resolution_clock::now(); @@ -60,8 +60,8 @@ void ReadAllData(std::unique_ptr<hidra2::DataBroker>* broker, Statistics* statis nfiles++; size += file_info.size; } - if (err->Explain() != hidra2::WorkerErrorMessage::kNoData) { - std::cout << "Read error" << std::endl; + if (err->GetErrorType() != hidra2::ErrorType::kEOF) { + std::cout << err->Explain() << std::endl; exit(EXIT_FAILURE); } diff --git a/tests/system_io/CMakeLists.txt b/tests/system_io/CMakeLists.txt index 595503fce8ff9e1c49b6fc7cf1f518276e231fce..ca5d8cd86e97c4c856be61e12d64f29155787cf8 100644 --- a/tests/system_io/CMakeLists.txt +++ b/tests/system_io/CMakeLists.txt @@ -1,5 +1,5 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.7) # needed for fixtures -add_subdirectory(read_files_in_folder) +add_subdirectory(read_folder_content) add_subdirectory(read_file_content) diff --git a/tests/system_io/read_file_content/CMakeLists.txt b/tests/system_io/read_file_content/CMakeLists.txt index 8109443ef271b5f29db5e6b13f2fb9c3f3863040..253fc7d58fbd0255f5d12b38c8374a2b6810570c 100644 --- a/tests/system_io/read_file_content/CMakeLists.txt +++ b/tests/system_io/read_file_content/CMakeLists.txt @@ -16,6 +16,6 @@ set_target_properties(${TARGET_NAME} PROPERTIES LINKER_LANGUAGE CXX) add_test_setup_cleanup(${TARGET_NAME}) add_integration_test(${TARGET_NAME} readfile "test/1 123") -add_integration_test(${TARGET_NAME} filenotfound "test_notexist notfound") -add_integration_test(${TARGET_NAME} filenoaccess "file_noaccess Permissiondenied") +add_integration_test(${TARGET_NAME} filenotfound "test_notexist Nosuchfileordirectory:test_notexist") +add_integration_test(${TARGET_NAME} filenoaccess "file_noaccess Permissiondenied:file_noaccess") diff --git a/tests/system_io/read_files_in_folder/CMakeLists.txt b/tests/system_io/read_folder_content/CMakeLists.txt similarity index 92% rename from tests/system_io/read_files_in_folder/CMakeLists.txt rename to tests/system_io/read_folder_content/CMakeLists.txt index a0065e1f8450f3f74e1936af8babee0c2bd3c05a..abad5b81ff9d22766c3b2d873ce09799b33f0e01 100644 --- a/tests/system_io/read_files_in_folder/CMakeLists.txt +++ b/tests/system_io/read_folder_content/CMakeLists.txt @@ -22,6 +22,6 @@ ELSE() ENDIF(WIN32) -add_integration_test(${TARGET_NAME} foldernotfound "test_notexist notfound") -add_integration_test(${TARGET_NAME} foldernoaccess "test_noaccess1 Permissiondenied") +add_integration_test(${TARGET_NAME} foldernotfound "test_notexist Nosuchfileordirectory:test_notexist") +add_integration_test(${TARGET_NAME} foldernoaccess "test_noaccess1 Permissiondenied:test_noaccess1") diff --git a/tests/system_io/read_files_in_folder/cleanup_linux.sh b/tests/system_io/read_folder_content/cleanup_linux.sh similarity index 100% rename from tests/system_io/read_files_in_folder/cleanup_linux.sh rename to tests/system_io/read_folder_content/cleanup_linux.sh diff --git a/tests/system_io/read_files_in_folder/cleanup_windows.bat b/tests/system_io/read_folder_content/cleanup_windows.bat similarity index 100% rename from tests/system_io/read_files_in_folder/cleanup_windows.bat rename to tests/system_io/read_folder_content/cleanup_windows.bat diff --git a/tests/system_io/read_files_in_folder/read_folder_content.cpp b/tests/system_io/read_folder_content/read_folder_content.cpp similarity index 100% rename from tests/system_io/read_files_in_folder/read_folder_content.cpp rename to tests/system_io/read_folder_content/read_folder_content.cpp diff --git a/tests/system_io/read_files_in_folder/setup_linux.sh b/tests/system_io/read_folder_content/setup_linux.sh similarity index 100% rename from tests/system_io/read_files_in_folder/setup_linux.sh rename to tests/system_io/read_folder_content/setup_linux.sh diff --git a/tests/system_io/read_files_in_folder/setup_windows.bat b/tests/system_io/read_folder_content/setup_windows.bat similarity index 100% rename from tests/system_io/read_files_in_folder/setup_windows.bat rename to tests/system_io/read_folder_content/setup_windows.bat diff --git a/worker/api/cpp/CMakeLists.txt b/worker/api/cpp/CMakeLists.txt index 60aeac037d5be6af04d18d08008b6ccc98a60290..49bcfa605ec2c49306a339193658f96447ab47bf 100644 --- a/worker/api/cpp/CMakeLists.txt +++ b/worker/api/cpp/CMakeLists.txt @@ -13,7 +13,7 @@ set(SOURCE_FILES # Library ################################ add_library(${TARGET_NAME} STATIC ${SOURCE_FILES} $<TARGET_OBJECTS:system_io> - $<TARGET_OBJECTS:data_structs>) + $<TARGET_OBJECTS:data_structs>) set (CMAKE_PREFIX_PATH "${LIBCURL_DIR}") find_package (CURL REQUIRED) diff --git a/worker/api/cpp/src/folder_data_broker.cpp b/worker/api/cpp/src/folder_data_broker.cpp index 11e44d96383ec1b2f5392f2a4e37ae9407b0c5eb..f312536460ac664c815cc71200498dfa6f311b67 100644 --- a/worker/api/cpp/src/folder_data_broker.cpp +++ b/worker/api/cpp/src/folder_data_broker.cpp @@ -37,7 +37,7 @@ Error FolderDataBroker::CanGetData(FileInfo* info, FileData* data, int nfile) co } if (nfile >= (int) filelist_.size()) { - return Error{TextError(WorkerErrorMessage::kNoData)}; + return Error{TextErrorWithType(WorkerErrorMessage::kNoData, ErrorType::kEOF)}; } return nullptr; } diff --git a/worker/api/cpp/src/http_client.cpp b/worker/api/cpp/src/http_client.cpp index 7b9c9836835830b643f1318de0a3d084fe276c6f..acfec717cbe1546e7f696c9a441c087933e4275c 100644 --- a/worker/api/cpp/src/http_client.cpp +++ b/worker/api/cpp/src/http_client.cpp @@ -15,7 +15,7 @@ Error HttpCodeToWorkerError(const HttpCode& code) { break; case HttpCode::NoContent: message = WorkerErrorMessage::kNoData; - break; + return TextErrorWithType(message, ErrorType::kEOF); case HttpCode::NotFound: message = WorkerErrorMessage::kSourceNotFound; break; diff --git a/worker/api/cpp/src/http_error.h b/worker/api/cpp/src/http_error.h index 2c3f5f362107670cbaf0ddc0d959bde03f5867b6..8ac563f57018cab3f33d6fde634e8f0e37376742 100644 --- a/worker/api/cpp/src/http_error.h +++ b/worker/api/cpp/src/http_error.h @@ -8,7 +8,7 @@ namespace hidra2 { class HttpError: public SimpleError { public: - HttpError(const std::string& error, HttpCode http_code): SimpleError{error}, http_code_{http_code} { + HttpError(const std::string& error, HttpCode http_code): SimpleError{error, ErrorType::kHttpError}, http_code_{http_code} { } HttpCode GetCode() const { return http_code_; diff --git a/worker/api/cpp/src/server_data_broker.cpp b/worker/api/cpp/src/server_data_broker.cpp index 8cd9c3efefabde5b295f577ae380453ce1097017..4712df342d35e765852035bbe7113eb8041fdce8 100644 --- a/worker/api/cpp/src/server_data_broker.cpp +++ b/worker/api/cpp/src/server_data_broker.cpp @@ -26,6 +26,7 @@ Error ServerDataBroker::GetFileInfoFromServer(FileInfo* info, const std::string& err = HttpCodeToWorkerError(code); if (err != nullptr) { + err->Append(responce); return err; } diff --git a/worker/api/cpp/unittests/test_folder_broker.cpp b/worker/api/cpp/unittests/test_folder_broker.cpp index d3a673f430b49972b1e00cb01658de15040c62fc..de0ac6969c083f8eb274cf73775187d5474d1015 100644 --- a/worker/api/cpp/unittests/test_folder_broker.cpp +++ b/worker/api/cpp/unittests/test_folder_broker.cpp @@ -195,6 +195,8 @@ TEST_F(FolderDataBrokerTests, GetNextFromEmptyFolderReturnsError) { FileInfo fi; auto err = data_broker->GetNext(&fi, nullptr); + ASSERT_THAT(err->GetErrorType(), Eq(hidra2::ErrorType::kEOF)); + ASSERT_THAT(err->Explain(), Eq(hidra2::WorkerErrorMessage::kNoData)); } diff --git a/worker/api/cpp/unittests/test_server_broker.cpp b/worker/api/cpp/unittests/test_server_broker.cpp index 4f0b6614fd8171f0a4a8e23b39ec4f9ce7e46f23..c4bdc10a576481acf79d06f8803875986b863990 100644 --- a/worker/api/cpp/unittests/test_server_broker.cpp +++ b/worker/api/cpp/unittests/test_server_broker.cpp @@ -24,6 +24,7 @@ using hidra2::SimpleError; using ::testing::AtLeast; using ::testing::Eq; +using ::testing::HasSubstr; using ::testing::Ne; using ::testing::Test; using ::testing::_; @@ -99,10 +100,24 @@ TEST_F(ServerDataBrokerTests, GetNextReturnsErrorFromHttpClient) { auto err = data_broker->GetNext(&info, nullptr); - ASSERT_THAT(err->Explain(), Eq(hidra2::WorkerErrorMessage::kSourceNotFound)); + ASSERT_THAT(err->Explain(), HasSubstr(hidra2::WorkerErrorMessage::kSourceNotFound)); + ASSERT_THAT(err->GetErrorType(), hidra2::ErrorType::kHttpError); ASSERT_THAT(dynamic_cast<HttpError*>(err.get())->GetCode(), Eq(HttpCode::NotFound)); } +TEST_F(ServerDataBrokerTests, GetNextReturnsEOFFromHttpClient) { + EXPECT_CALL(mock_http_client, Get_t(_, _, _)).WillOnce(DoAll( + SetArgPointee<1>(HttpCode::NoContent), + SetArgPointee<2>(nullptr), + Return(""))); + + auto err = data_broker->GetNext(&info, nullptr); + + ASSERT_THAT(err->Explain(), HasSubstr(hidra2::WorkerErrorMessage::kNoData)); + ASSERT_THAT(err->GetErrorType(), hidra2::ErrorType::kEOF); +} + + FileInfo CreateFI() { FileInfo fi; fi.size = 100; diff --git a/worker/tools/folder_to_db/src/main.cpp b/worker/tools/folder_to_db/src/main.cpp index 8e79fed17d248dfb4d2aad378187a49994e1c707..c0440577a6bc89fdf233765de6aaca20c455b672 100644 --- a/worker/tools/folder_to_db/src/main.cpp +++ b/worker/tools/folder_to_db/src/main.cpp @@ -84,7 +84,7 @@ int main(int argc, char* argv[]) { auto err = importer.Convert(import_params.uri, import_params.folder, import_params.db_name, &statistics); if (err != nullptr) { - std::cout << "Error import to database" << std::endl; + std::cout << "Error import to database: " << err->Explain() << std::endl; return 1; }