diff --git a/CMakeModules/testing_cpp.cmake b/CMakeModules/testing_cpp.cmake index 0ed139b3f037e6a88f3ef036f9e008c7f3d76958..451ce81acc98295aba68b60d6d094c80ad9b75ab 100644 --- a/CMakeModules/testing_cpp.cmake +++ b/CMakeModules/testing_cpp.cmake @@ -119,8 +119,12 @@ function(add_script_test testname exename) add_test(NAME test-${testname} COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/check_windows.bat ${args}) ELSE() + set(memargs ${MEMORYCHECK_COMMAND} ${MEMORYCHECK_COMMAND_OPTIONS} ${exename}) + separate_arguments(memargs) add_test(NAME test-${testname} COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/check_linux.sh ${args}) + add_test(NAME memtest-${testname} COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/check_linux.sh + ${memargs}) ENDIF() set_tests_properties(test-${testname} PROPERTIES LABELS "example;all" diff --git a/common/cpp/include/common/file_info.h b/common/cpp/include/common/file_info.h index d10773beb6b2c273239b7c81fdf9e5ef644558e1..efb2d63125e2d2dad47c7397f4befecd233e7b01 100644 --- a/common/cpp/include/common/file_info.h +++ b/common/cpp/include/common/file_info.h @@ -13,6 +13,7 @@ struct FileInfo { std::string relative_path; std::chrono::system_clock::time_point modify_date; uint64_t size{0}; + uint64_t id{0}; }; using FileData = std::unique_ptr<uint8_t[]>; diff --git a/common/cpp/include/database/database.h b/common/cpp/include/database/database.h index f1bdb9b6ff9b163c2c1620b4446f3457d9b5a313..adc4dab358239bc80ec821e0dc737e1c5ba8b366 100644 --- a/common/cpp/include/database/database.h +++ b/common/cpp/include/database/database.h @@ -8,12 +8,13 @@ namespace hidra2 { enum class DBError { - kNoError, kConnectionError, - kImportError, + kInsertError, + kDuplicateID, kAlreadyConnected, kNotConnected, - kBadAddress + kBadAddress, + kNoError }; constexpr char kDBName[] = "data"; @@ -22,7 +23,7 @@ class Database { public: virtual DBError Connect(const std::string& address, const std::string& database, const std::string& collection ) = 0; - virtual DBError Import(const FileInfos& files) const = 0; + virtual DBError Insert(const FileInfo& file) const = 0; virtual ~Database() = default; }; diff --git a/common/cpp/include/database/mongodb_client.h b/common/cpp/include/database/mongodb_client.h index 61cf5bbfc467417182064a82ef00d03b85468ae8..e7989b92d7ce08d40ac45cb0708274a28cb92dd6 100644 --- a/common/cpp/include/database/mongodb_client.h +++ b/common/cpp/include/database/mongodb_client.h @@ -28,7 +28,7 @@ class MongoDBClient final: public Database { MongoDBClient(); DBError Connect(const std::string& address, const std::string& database, const std::string& collection ) override; - DBError Import(const FileInfos& files) const override; + DBError Insert(const FileInfo& file) const override; ~MongoDBClient() override; private: mongoc_client_t* client_{nullptr}; @@ -39,7 +39,7 @@ class MongoDBClient final: public Database { DBError InitializeClient(const std::string& address); void InitializeCollection(const std::string& database_name, const std::string& collection_name); - + DBError ImportMany(const FileInfos& files) const; DBError Ping(); DBError TryConnectDatabase(); }; diff --git a/common/cpp/src/database/mongodb_client.cpp b/common/cpp/src/database/mongodb_client.cpp index 4f014d41dc712c73f773021d33ce8cf1151864d8..5452e8d48597d91d9c6a2c43268d4c985c37e236 100644 --- a/common/cpp/src/database/mongodb_client.cpp +++ b/common/cpp/src/database/mongodb_client.cpp @@ -1,7 +1,18 @@ #include "database/mongodb_client.h" +#include <string> + +using std::string; + namespace hidra2 { +struct BsonDestroyFunctor { + void operator() (_bson_t* bson) const { + bson_destroy(bson); + } +}; +using bson_p = std::unique_ptr<bson_t, BsonDestroyFunctor>; + MongoDbInstance::MongoDbInstance() { mongoc_init (); } @@ -29,7 +40,7 @@ MongoDBClient::MongoDBClient() { MongoDbInstance::Instantiate(); } -DBError MongoDBClient::InitializeClient(const std::string& address) { +DBError MongoDBClient::InitializeClient(const string& address) { auto uri_str = DBAddress(address); client_ = mongoc_client_new (uri_str.c_str()); if (client_ == nullptr) { @@ -39,8 +50,8 @@ DBError MongoDBClient::InitializeClient(const std::string& address) { } -void MongoDBClient::InitializeCollection(const std::string& database_name, - const std::string& collection_name) { +void MongoDBClient::InitializeCollection(const string& database_name, + const string& collection_name) { collection_ = mongoc_client_get_collection (client_, database_name.c_str(), collection_name.c_str()); } @@ -53,8 +64,8 @@ DBError MongoDBClient::TryConnectDatabase() { return err; } -DBError MongoDBClient::Connect(const std::string& address, const std::string& database_name, - const std::string& collection_name) { +DBError MongoDBClient::Connect(const string& address, const string& database_name, + const string& collection_name) { if (connected_) { return DBError::kAlreadyConnected; } @@ -73,7 +84,7 @@ DBError MongoDBClient::Connect(const std::string& address, const std::string& da return err; } -std::string MongoDBClient::DBAddress(const std::string& address) const { +string MongoDBClient::DBAddress(const string& address) const { return "mongodb://" + address + "/?appname=hidra2"; } @@ -82,14 +93,38 @@ void MongoDBClient::CleanUp() { mongoc_client_destroy (client_); } -DBError MongoDBClient::Import(const FileInfos& files) const { +string JsonFromFileInfo(const FileInfo& file) { + auto periods = file.modify_date.time_since_epoch().count(); + string s = "{\"_id\":" + std::to_string(file.id) + "," + "\"size\":" + std::to_string(file.size) + "," + "\"base_name\":\"" + file.base_name + "\"," + "\"lastchange\":" + std::to_string(periods) + "," + "\"relative_path\":\"" + file.relative_path + "\"}"; + return s; +} + +DBError MongoDBClient::Insert(const FileInfo& file) const { if (!connected_) { return DBError::kNotConnected; } + bson_error_t err; + auto s = JsonFromFileInfo(file); + const char* json = s.c_str(); + + bson_p update{bson_new_from_json((const uint8_t*)json, -1, &err)}; + + if (!mongoc_collection_insert_one(collection_, update.get(), NULL, NULL, &err)) { + if (err.code == MONGOC_ERROR_DUPLICATE_KEY) { + return DBError::kDuplicateID; + } + return DBError::kInsertError; + } + return DBError::kNoError; } + MongoDBClient::~MongoDBClient() { if (!connected_) { return; diff --git a/common/cpp/src/system_io/system_io.cpp b/common/cpp/src/system_io/system_io.cpp index f3f79eba1045439ba911cc675be17d750e6bbbd8..ec4c7f8bae613592f5d9c983bfac8b96f3e9bb8a 100644 --- a/common/cpp/src/system_io/system_io.cpp +++ b/common/cpp/src/system_io/system_io.cpp @@ -43,6 +43,7 @@ void SystemIO::ReadWholeFile(int fd, uint8_t* array, uint64_t fsize, IOError* er } FileData SystemIO::GetDataFromFile(const std::string& fname, uint64_t fsize, IOError* err) const noexcept { + errno = 0; int fd = open(fname.c_str(), O_RDONLY); *err = IOErrorFromErrno(); if (*err != IOError::kNoError) { @@ -62,7 +63,7 @@ FileData SystemIO::GetDataFromFile(const std::string& fname, uint64_t fsize, IOE close(fd); return nullptr; } - + errno = 0; close(fd); *err = IOErrorFromErrno(); if (*err != IOError::kNoError) { @@ -86,6 +87,14 @@ void StripBasePath(const std::string& folder, FileInfos* file_list) { } } +void AssignIDs(FileInfos* file_list) { + int64_t id = 0; + for (auto& file : *file_list) { + file.id = ++id; + } +} + + FileInfos SystemIO::FilesInFolder(const std::string& folder, IOError* err) const { FileInfos files{}; CollectFileInformationRecursivly(folder, &files, err); @@ -94,6 +103,7 @@ FileInfos SystemIO::FilesInFolder(const std::string& folder, IOError* err) const } StripBasePath(folder, &files); SortFileList(&files); + AssignIDs(&files); return files; } diff --git a/common/cpp/src/system_io/system_io_linux.cpp b/common/cpp/src/system_io/system_io_linux.cpp index 263ac3b6f0ac9d496f699f6d92ff79fa043f4b0a..247c105aa4328cd8892d0d42dc6734e6a2db940f 100644 --- a/common/cpp/src/system_io/system_io_linux.cpp +++ b/common/cpp/src/system_io/system_io_linux.cpp @@ -48,6 +48,7 @@ void SetFileName(const string& path, const string& name, FileInfo* file_info) { struct stat FileStat(const string& fname, IOError* err) { struct stat t_stat {}; + errno = 0; int res = stat(fname.c_str(), &t_stat); if (res < 0) { *err = IOErrorFromErrno(); @@ -84,19 +85,23 @@ void ProcessFileEntity(const struct dirent* entity, const std::string& path, if (*err != IOError::kNoError) { return; } - files->push_back(file_info); } void SystemIO::CollectFileInformationRecursivly(const std::string& path, FileInfos* files, IOError* err) const { + errno = 0; auto dir = opendir((path).c_str()); if (dir == nullptr) { *err = IOErrorFromErrno(); return; } - - while (struct dirent* current_entity = readdir(dir)) { + while (true) { + errno = 0; + struct dirent* current_entity = readdir(dir); + if (!current_entity) { + break; + } if (IsDirectory(current_entity)) { CollectFileInformationRecursivly(path + "/" + current_entity->d_name, files, err); @@ -104,6 +109,7 @@ void SystemIO::CollectFileInformationRecursivly(const std::string& path, ProcessFileEntity(current_entity, path, files, err); } if (*err != IOError::kNoError) { + errno = 0; closedir(dir); return; } diff --git a/examples/worker/process_folder/CMakeLists.txt b/examples/worker/process_folder/CMakeLists.txt index f023b46f85b975a24fb970daeb5724eeea23c5c5..0c0d05d73cb46d7295e078d39f74090acd9a3a95 100644 --- a/examples/worker/process_folder/CMakeLists.txt +++ b/examples/worker/process_folder/CMakeLists.txt @@ -15,7 +15,7 @@ if (CMAKE_COMPILER_IS_GNUCXX) set_target_properties(${TARGET_NAME} PROPERTIES LINK_FLAGS_DEBUG "--coverage") endif() -add_script_test("${TARGET_NAME}" "") +add_script_test("${TARGET_NAME}" ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}) set (dir examples/worker/process_folder) diff --git a/examples/worker/process_folder/check_linux.sh b/examples/worker/process_folder/check_linux.sh index 1c3dbc0365512bae744d4d8fdb9f3c45d62cb9bd..905190558f4918d431128169c854a48ba91c564c 100644 --- a/examples/worker/process_folder/check_linux.sh +++ b/examples/worker/process_folder/check_linux.sh @@ -5,6 +5,6 @@ set -e mkdir -p test touch test/1 -./worker_processfolder test | grep "Processed 1 file(s)" +$@ test | grep "Processed 1 file(s)" rm -rf test diff --git a/tests/mongo_db/CMakeLists.txt b/tests/mongo_db/CMakeLists.txt index e58cca746bf9722086ac3419c4632f4f9d50666c..74a0fc66bd5f4e34dec0ee589175d9099b43e406 100644 --- a/tests/mongo_db/CMakeLists.txt +++ b/tests/mongo_db/CMakeLists.txt @@ -1,5 +1,5 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.7) # needed for fixtures add_subdirectory(connect) -add_subdirectory(import) +add_subdirectory(insert) diff --git a/tests/mongo_db/connect/connect_mongodb.cpp b/tests/mongo_db/connect/connect_mongodb.cpp index 0cfeccec00bbd2fe641678bf5d3f30cf4a1b2cdb..12247a5241bcd145ad476b497f01fc5aefe6dccb 100644 --- a/tests/mongo_db/connect/connect_mongodb.cpp +++ b/tests/mongo_db/connect/connect_mongodb.cpp @@ -33,7 +33,7 @@ struct Args { std::string address; std::string database_name; std::string collection_name; - std::string expect; + std::string keyword; }; @@ -51,7 +51,7 @@ int main(int argc, char* argv[]) { hidra2::MongoDBClient db; auto err = db.Connect(args.address, args.database_name, args.collection_name); - Assert(err, args.expect); + Assert(err, args.keyword); if (err == DBError::kNoError) { err = db.Connect(args.address, args.database_name, args.collection_name); diff --git a/tests/mongo_db/import/CMakeLists.txt b/tests/mongo_db/import/CMakeLists.txt deleted file mode 100644 index 10ed5c9cf3a54079548e0a4d218ed38be3469f1f..0000000000000000000000000000000000000000 --- a/tests/mongo_db/import/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -set(TARGET_NAME import_mongodb) -set(SOURCE_FILES import_mongodb.cpp) - - -################################ -# Executable and link -################################ -add_executable(${TARGET_NAME} ${SOURCE_FILES}) -target_link_libraries(${TARGET_NAME} test_common mongo_db) -target_include_directories(${TARGET_NAME} PUBLIC ${HIDRA2_CXX_COMMON_INCLUDE_DIR}) - -################################ -# Testing -################################ - -add_integration_test(${TARGET_NAME} importOK "ok OK") -add_integration_test(${TARGET_NAME} importFailsWhenNotConnected "notconnected NotConnected") - - diff --git a/tests/mongo_db/insert/CMakeLists.txt b/tests/mongo_db/insert/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..81d715feed25bb77205c2206ba47b7a5e66d5d70 --- /dev/null +++ b/tests/mongo_db/insert/CMakeLists.txt @@ -0,0 +1,24 @@ +set(TARGET_NAME upsert_mongodb) +set(SOURCE_FILES insert_mongodb.cpp) + + +################################ +# Executable and link +################################ +add_executable(${TARGET_NAME} ${SOURCE_FILES}) +target_link_libraries(${TARGET_NAME} test_common mongo_db) +target_include_directories(${TARGET_NAME} PUBLIC ${HIDRA2_CXX_COMMON_INCLUDE_DIR}) + +################################ +# Testing +################################ +add_test_setup_cleanup(${TARGET_NAME}) +add_integration_test(${TARGET_NAME} upsertOK "OK 1" "OK 2") +add_integration_test(${TARGET_NAME} upsertFailsWhenNotConnected + "NotConnected 3" + "NotConnected 4") +add_integration_test(${TARGET_NAME} upsertFailsForDuplicateID + "DuplicateID 6" + "DuplicateID 5") + + diff --git a/tests/mongo_db/import/cleanup_linux.sh b/tests/mongo_db/insert/cleanup_linux.sh similarity index 100% rename from tests/mongo_db/import/cleanup_linux.sh rename to tests/mongo_db/insert/cleanup_linux.sh diff --git a/tests/mongo_db/import/import_mongodb.cpp b/tests/mongo_db/insert/insert_mongodb.cpp similarity index 60% rename from tests/mongo_db/import/import_mongodb.cpp rename to tests/mongo_db/insert/insert_mongodb.cpp index 3ed0b73a233ca5f92cca40bd95d47d263370f2bc..91a4422e7eb0e81cd3cb2814a2b4f3024acc53a8 100644 --- a/tests/mongo_db/import/import_mongodb.cpp +++ b/tests/mongo_db/insert/insert_mongodb.cpp @@ -1,5 +1,5 @@ #include <iostream> - +#include <chrono> #include "database/mongodb_client.h" #include "testing.h" @@ -12,12 +12,16 @@ using hidra2::DBError; void Assert(DBError error, const std::string& expect) { std::string result; switch (error) { - case DBError::kImportError: - result = "ImportError"; + case DBError::kInsertError: + result = "InsertError"; break; case DBError::kNotConnected: result = "NotConnected"; break; + case DBError::kDuplicateID: + result = "DuplicateID"; + break; + default: result = "OK"; break; @@ -27,9 +31,8 @@ void Assert(DBError error, const std::string& expect) { } struct Args { - std::string instruction; - std::string expect; - + std::string keyword; + int file_id; }; Args GetArgs(int argc, char* argv[]) { @@ -37,7 +40,7 @@ Args GetArgs(int argc, char* argv[]) { std::cout << "Wrong number of arguments" << std::endl; exit(EXIT_FAILURE); } - return Args{argv[1], argv[2]}; + return Args{argv[1], atoi(argv[2])}; } @@ -45,24 +48,27 @@ int main(int argc, char* argv[]) { auto args = GetArgs(argc, argv); hidra2::MongoDBClient db; - - hidra2::FileInfos files; hidra2::FileInfo fi; fi.size = 100; fi.base_name = "1"; - files.emplace_back(fi); - fi.base_name = "2"; - files.emplace_back(fi); + fi.id = args.file_id; + fi.relative_path = "relpath"; + fi.modify_date = std::chrono::system_clock::now(); - if (args.instruction != "notconnected") { + if (args.keyword != "NotConnected") { db.Connect("127.0.0.1", "data", "test"); } - auto err = db.Import(files); + auto err = db.Insert(fi); - Assert(err, args.expect); + if (args.keyword == "DuplicateID") { + Assert(err, "OK"); + err = db.Insert(fi); + } + + Assert(err, args.keyword); - return 0; -} + return 0; +} diff --git a/tests/mongo_db/import/setup_linux.sh b/tests/mongo_db/insert/setup_linux.sh similarity index 100% rename from tests/mongo_db/import/setup_linux.sh rename to tests/mongo_db/insert/setup_linux.sh diff --git a/tests/system_io/read_files_in_folder/read_folder_content.cpp b/tests/system_io/read_files_in_folder/read_folder_content.cpp index 926126dc964dcdde192734183def7a078420d2d6..9c0e58ea840e6498aace9677330e66dd9c41d2c4 100644 --- a/tests/system_io/read_files_in_folder/read_folder_content.cpp +++ b/tests/system_io/read_files_in_folder/read_folder_content.cpp @@ -20,13 +20,16 @@ int main(int argc, char* argv[]) { auto files = io->FilesInFolder(argv[1], &err); std::string result; + int64_t id = 0; switch (err) { case IOError::kFileNotFound: result = "notfound"; break; case IOError::kNoError: - for(auto file_info : files) + for(auto file_info : files) { + M_AssertEq(file_info.id, ++id); result += file_info.relative_path + file_info.base_name; + } break; case IOError::kPermissionDenied: result = "noaccess"; diff --git a/tests/worker/folder_to_db/check_linux.sh b/tests/worker/folder_to_db/check_linux.sh index 8cd23cb10dee268a0f0999d012b4300bd803d306..175509cb04a78d45d7f80ca55b6e2351ca793f62 100644 --- a/tests/worker/folder_to_db/check_linux.sh +++ b/tests/worker/folder_to_db/check_linux.sh @@ -17,10 +17,8 @@ touch test/file2 sleep 0.1 touch test/file1 -$1 test 127.0.0.1 +$@ test 127.0.0.1 echo "show collections" | mongo ${database_name} | grep test echo "db.test.find({"_id":1})" | mongo ${database_name} | grep file2 -echo "db.test.find("_id":2)" | mongo ${database_name} | grep file1 - - +echo "db.test.find({"_id":2})" | mongo ${database_name} | grep file1 diff --git a/worker/tools/folder_to_db/src/folder_db_importer.cpp b/worker/tools/folder_to_db/src/folder_db_importer.cpp index e858f88b781ebf5b5a2487de4e3223721b14c55f..406ee98313003cebc8657b83e9f6399e0c35f59b 100644 --- a/worker/tools/folder_to_db/src/folder_db_importer.cpp +++ b/worker/tools/folder_to_db/src/folder_db_importer.cpp @@ -27,7 +27,7 @@ FolderToDbImportError MapDBError(DBError db_err) { case DBError::kConnectionError: err = FolderToDbImportError::kDBConnectionError; break; - case DBError::kImportError: + case DBError::kInsertError: err = FolderToDbImportError::kImportError; break; } @@ -44,12 +44,23 @@ FolderToDbImportError FolderToDbImporter::ConnectToDb(const std::string& uri, co return MapDBError(err); } -FolderToDbImportError FolderToDbImporter::ImportFilelist(FileInfos file_list) const { - auto err = db__->Import(file_list); +FolderToDbImportError FolderToDbImporter::ImportSingleFile(const FileInfo& file) const { + auto err = db__->Insert(file); return MapDBError(err); } +FolderToDbImportError FolderToDbImporter::ImportFilelist(const FileInfos& file_list) const { + for (auto& file : file_list) { + auto err = ImportSingleFile(file); + if (err != FolderToDbImportError::kOK) { + return err; + } + } + return FolderToDbImportError::kOK; +} + + FileInfos FolderToDbImporter::GetFilesInFolder(const std::string& folder, FolderToDbImportError* err) const { IOError err_io; auto file_list = io__->FilesInFolder(folder, &err_io); diff --git a/worker/tools/folder_to_db/src/folder_db_importer.h b/worker/tools/folder_to_db/src/folder_db_importer.h index 48cf1449c55a5bbe1e5429fc0822480aacbf4b3e..8edb97912cc258c3d41a36f2c513e9116dad900f 100644 --- a/worker/tools/folder_to_db/src/folder_db_importer.h +++ b/worker/tools/folder_to_db/src/folder_db_importer.h @@ -24,7 +24,8 @@ class FolderToDbImporter { private: FolderToDbImportError ConnectToDb(const std::string& uri, const std::string& folder) const; FileInfos GetFilesInFolder(const std::string& folder, FolderToDbImportError* err) const; - FolderToDbImportError ImportFilelist(FileInfos file_list) const; + FolderToDbImportError ImportSingleFile(const FileInfo& file) const; + FolderToDbImportError ImportFilelist(const FileInfos& file_list) const; }; diff --git a/worker/tools/folder_to_db/unittests/test_folder_to_db.cpp b/worker/tools/folder_to_db/unittests/test_folder_to_db.cpp index 6b6f5c4b2fbf7436c0e3de2caabb5a290259b1e0..45303a8331d49e18d4400e9cc178b4132dcdcd63 100644 --- a/worker/tools/folder_to_db/unittests/test_folder_to_db.cpp +++ b/worker/tools/folder_to_db/unittests/test_folder_to_db.cpp @@ -23,6 +23,7 @@ using ::testing::_; using ::testing::Mock; using ::testing::NiceMock; using ::testing::Ref; +using ::testing::Return; using hidra2::FolderToDbImporter; using hidra2::FolderToDbImportError; @@ -51,7 +52,7 @@ TEST(FolderDBConverter, SetCorrectDB) { class MockDatabase : public Database { public: MOCK_METHOD3(Connect, DBError (const std::string&, const std::string&, const std::string&)); - MOCK_CONST_METHOD1(Import, DBError (const FileInfos&)); + MOCK_CONST_METHOD1(Insert, DBError (const FileInfo&)); // stuff to test db destructor is called and avoid "uninteresting call" messages MOCK_METHOD0(Die, void()); @@ -60,19 +61,37 @@ class MockDatabase : public Database { Die(); } bool check_destructor{false}; - }; +FileInfos CreateTestFileInfos() { + FileInfos file_infos; + FileInfo fi; + fi.size = 100; + fi.base_name = "1"; + file_infos.push_back(fi); + fi.base_name = "2"; + file_infos.push_back(fi); + fi.base_name = "3"; + file_infos.push_back(fi); + return file_infos; +} + class FolderDBConverterTests : public Test { public: FolderToDbImporter converter{}; NiceMock<MockDatabase> mock_db; NiceMock<MockIO> mock_io; + FileInfos file_infos; void SetUp() override { converter.db__ = std::unique_ptr<Database> {&mock_db}; converter.io__ = std::unique_ptr<IO> {&mock_io}; - + file_infos = CreateTestFileInfos(); + ON_CALL(mock_db, Connect(_, _, _)) + .WillByDefault(Return(DBError::kNoError)); + ON_CALL(mock_io, FilesInFolder(_, _)). + WillByDefault(DoAll(testing::SetArgPointee<1>(IOError::kNoError), + testing::Return(file_infos))); } void TearDown() override { converter.db__.release(); @@ -86,7 +105,6 @@ TEST_F(FolderDBConverterTests, ErrorWhenCannotConnect) { std::string uri{"db_address"}; - EXPECT_CALL(mock_db, Connect(uri, kDBName, "")). WillOnce(testing::Return(DBError::kConnectionError)); @@ -104,22 +122,19 @@ TEST_F(FolderDBConverterTests, ErrorWhenCannotGetFileList) { std::string folder{"folder"}; EXPECT_CALL(mock_io, FilesInFolder(folder, _)). - WillOnce(DoAll(testing::SetArgPointee<1>(IOError::kReadError), testing::Return(FileInfos {}))); - + WillOnce(DoAll(testing::SetArgPointee<1>(IOError::kReadError), + testing::Return(FileInfos {}))); auto error = converter.Convert(folder, ""); ASSERT_THAT(error, Eq(FolderToDbImportError::kIOError)); } -TEST_F(FolderDBConverterTests, ErrorWhenCannotImportFileListToDb) { - EXPECT_CALL(mock_io, FilesInFolder(_, _)). - WillOnce(DoAll(testing::SetArgPointee<1>(IOError::kNoError), - testing::Return(FileInfos {}))); +TEST_F(FolderDBConverterTests, ErrorWhenCannotImportFileListToDb) { - EXPECT_CALL(mock_db, Import(_)). - WillOnce(testing::Return(DBError::kImportError)); + EXPECT_CALL(mock_db, Insert(_)). + WillOnce(testing::Return(DBError::kInsertError)); auto error = converter.Convert("", ""); ASSERT_THAT(error, Eq(FolderToDbImportError::kImportError)); @@ -127,39 +142,19 @@ TEST_F(FolderDBConverterTests, ErrorWhenCannotImportFileListToDb) { } // a matcher to compare file_infos (size and basename only) for testing purposes // (we do not want to create an == operator for FileInfo) -MATCHER_P(CompareFileInfos, file_infos, "") { - if (arg.size() != file_infos.size()) return false; - for (int i = 0; i < arg.size(); i++) { - if (arg[i].size != file_infos[i].size) return false; - if (arg[i].base_name != file_infos[i].base_name) return false; - } +MATCHER_P(CompareFileInfo, file, "") { + if (arg.size != file.size) return false; + if (arg.base_name != file.base_name) return false; return true; } -FileInfos CreateTestFileInfos() { - FileInfos file_infos; - FileInfo fi; - fi.size = 100; - fi.base_name = "1"; - file_infos.push_back(fi); - fi.base_name = "2"; - file_infos.push_back(fi); - fi.base_name = "3"; - file_infos.push_back(fi); - return file_infos; -} +TEST_F(FolderDBConverterTests, PassesFileListToInsert) { -TEST_F(FolderDBConverterTests, PassesFileListToImport) { - - auto file_infos = CreateTestFileInfos(); - - EXPECT_CALL(mock_io, FilesInFolder(_, _)). - WillOnce(DoAll(testing::SetArgPointee<1>(IOError::kNoError), - testing::Return(file_infos))); - - EXPECT_CALL(mock_db, Import(CompareFileInfos(file_infos))). - WillOnce(testing::Return(DBError::kNoError)); + for (auto& file : file_infos) { + EXPECT_CALL(mock_db, Insert(CompareFileInfo(file))). + WillOnce(testing::Return(DBError::kNoError)); + } auto error = converter.Convert("", ""); ASSERT_THAT(error, Eq(FolderToDbImportError::kOK));