diff --git a/conanfile.txt b/conanfile.txt index ccd05f44e4855c4d4b13dc1fbc7df8554dd4e8ad..73d40c4c18c07d61782b86f8399942a6fb8be0bf 100644 --- a/conanfile.txt +++ b/conanfile.txt @@ -1,5 +1,5 @@ [requires] -caosdb/0.0.11 +caosdb/0.0.13 gtest/1.11.0 [generators] diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index ecb011e99179399e62f646f3027951aff0163466..c388869d9b0df41f78f478145c61f653bde21c51 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -24,7 +24,7 @@ set(test_cases test_connection test_transaction - #test_file_transmission TODO add once fixed + test_list_properties test_ccaosdb ) @@ -83,7 +83,7 @@ if(LINTING) "--warnings-as-errors=*" "--fix") set(_CMAKE_CXX_CLANG_TIDY_CHECKS - "--checks=*,-fuchsia-*,-llvmlibc-*,-cert-err58-cpp,-cppcoreguidelines-avoid-non-const-global-variables,-cppcoreguidelines-owning-memory,-modernize-use-trailing-return-type,-google-readability-avoid-underscore-in-googletest-name,-cppcoreguidelines-avoid-magic-numbers,-readability-magic-numbers,-cppcoreguidelines-avoid-goto,-hicpp-avoid-goto,-readability-function-cognitive-complexity,-cppcoreguidelines-non-private-member-variables-in-classes,-misc-non-private-member-variables-in-classes,-cppcoreguidelines-pro-type-vararg,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-hicpp-no-array-decay") + "--checks=*,-fuchsia-*,-llvmlibc-*,-cert-err58-cpp,-cppcoreguidelines-avoid-non-const-global-variables,-cppcoreguidelines-owning-memory,-modernize-use-trailing-return-type,-google-readability-avoid-underscore-in-googletest-name,-cppcoreguidelines-avoid-magic-numbers,-readability-magic-numbers,-cppcoreguidelines-avoid-goto,-hicpp-avoid-goto,-readability-function-cognitive-complexity,-cppcoreguidelines-pro-type-vararg,-cppcoreguidelines-non-private-member-variables-in-classes,-misc-non-private-member-variables-in-classes,-cppcoreguidelines-pro-type-vararg,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-hicpp-no-array-decay") endif() else() message(STATUS "LINTING is OFF") diff --git a/test/test_ccaosdb.cpp b/test/test_ccaosdb.cpp index facaf9a86b896ca4ddcf9b4ce5532d67bc84aa13..c4a45720f7670a9b6e7e29f885d7155decfebb62 100644 --- a/test/test_ccaosdb.cpp +++ b/test/test_ccaosdb.cpp @@ -189,8 +189,8 @@ TEST_F(test_ccaosdb, test_single_id_retrieve) { EXPECT_EQ(return_code, 0); EXPECT_EQ(*count, 0); - char out[255] = {"255"}; // NOLINT - return_code = caosdb_entity_entity_get_name(&entity, out); + char *out = nullptr; // NOLINT + return_code = caosdb_entity_entity_get_name(&entity, &out); EXPECT_EQ(return_code, 0); EXPECT_STREQ(out, "unit"); @@ -237,8 +237,8 @@ TEST_F(test_ccaosdb, test_multi_id_retrieve) { EXPECT_EQ(return_code, 0); EXPECT_EQ(*count, 0); - char out[255] = {"255"}; // NOLINT - return_code = caosdb_entity_entity_get_name(&entity, out); + char *out = nullptr; // NOLINT + return_code = caosdb_entity_entity_get_name(&entity, &out); EXPECT_EQ(return_code, 0); EXPECT_STREQ(out, "unit"); diff --git a/test/test_connection.cpp b/test/test_connection.cpp index 672ef73b78673478e3488adab8be28e8b5add980..678035b50b4fee53cc246a7335ae5fb74bfb1eca 100644 --- a/test/test_connection.cpp +++ b/test/test_connection.cpp @@ -28,9 +28,9 @@ #include "caosdb/info.h" // for VersionInfo #include "caosdb/utility.h" // for get_env_var #include "caosdb_test_utility.h" // for EXPECT_THROW_MESSAGE -#include <gtest/gtest-message.h> // NOLINT TODO ?? for Message -#include <gtest/gtest-test-part.h> // NOLINT for SuiteApiResolver, TestPartR... -#include "gtest/gtest_pred_impl.h" // NOLINT for Test, TestInfo, TEST, EXPEC... +#include "gtest/gtest_pred_impl.h" // NOLINT TODO how to fix this? for Test, TestInfo, TEST, EXPEC... +#include <gtest/gtest-message.h> // for Message +#include <gtest/gtest-test-part.h> // for SuiteApiResolver, TestPartR... #include <memory> // for allocator, unique_ptr, __sh... #include <string> // for stoi, string diff --git a/test/test_file_transmission.cpp b/test/test_file_transmission.cpp deleted file mode 100644 index fb42d893783534097f834235d4cfaba789f37c8d..0000000000000000000000000000000000000000 --- a/test/test_file_transmission.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/* - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2021 Timm Fitschen <t.fitschen@indiscale.com> - * Copyright (C) 2021 IndiScale GmbH <info@indiscale.com> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - * - */ -#include "caosdb/connection.h" // for Connection, ConnectionManager -#include "caosdb/entity.h" -#include "caosdb/entity/v1alpha1/main.pb.h" -#include "caosdb/transaction.h" // for Transaction, UniqueRe... -#include "gtest/gtest-message.h" // for Message -#include "gtest/gtest-test-part.h" // for TestPartResult, SuiteApiResolver -#include "gtest/gtest_pred_impl.h" // for Test, EXPECT_EQ, AssertionResult -#include <memory> // for unique_ptr, allocator, __shar... -#include <string> // for string -namespace caosdb::transaction { -using caosdb::entity::Entity; -using caosdb::entity::v1alpha1::FileDownloadResponse; -using caosdb::entity::v1alpha1::FileUploadResponse; -using caosdb::entity::v1alpha1::RegisterFileDownloadResponse; -using caosdb::entity::v1alpha1::RegisterFileUploadResponse; -using caosdb::entity::v1alpha1::RegistrationStatus; -using caosdb::entity::v1alpha1::TransmissionStatus; - - -// TODO(tf) this file is currently not used (see CMakeLists.txt) -// Is it still necessary or is it obsolete due to test_transaction.cpp? -// RegisterFileDownloadResponse is currently not defined by proto or the h -// file. - -class test_file_transmission : public ::testing::Test { -protected: - void SetUp() override {} - - void TearDown() override { - // TODO(tf): delete all created entities - } -}; - -TEST_F(test_file_transmission, register_file_upload) { - const auto &connection = - caosdb::connection::ConnectionManager::GetDefaultConnection(); - - auto transaction(connection->CreateTransaction()); - RegisterFileUploadResponse response; - EXPECT_EQ(response.status(), - RegistrationStatus::REGISTRATION_STATUS_UNSPECIFIED); - - transaction->RegisterUploadFile(&response); - - EXPECT_EQ(response.status(), - RegistrationStatus::REGISTRATION_STATUS_ACCEPTED); - EXPECT_FALSE(response.registration_id().empty()); -} - -TEST_F(test_file_transmission, file_upload) { - const auto &connection = - caosdb::connection::ConnectionManager::GetDefaultConnection(); - - auto transaction(connection->CreateTransaction()); - RegisterFileUploadResponse registration_response; - - transaction->RegisterUploadFile(®istration_response); - ASSERT_EQ(registration_response.status(), - RegistrationStatus::REGISTRATION_STATUS_ACCEPTED); - auto registration_id = registration_response.registration_id(); - - FileUploadResponse upload_response; - transaction->UploadFile(&upload_response, registration_id); - - EXPECT_EQ(upload_response.status(), - TransmissionStatus::TRANSMISSION_STATUS_GO_ON); -} - -TEST_F(test_file_transmission, file_insertion) { - const auto &connection = - caosdb::connection::ConnectionManager::GetDefaultConnection(); - - auto transaction(connection->CreateTransaction()); - RegisterFileUploadResponse registration_response; - - transaction->RegisterUploadFile(®istration_response); - ASSERT_EQ(registration_response.status(), - RegistrationStatus::REGISTRATION_STATUS_ACCEPTED); - auto registration_id = registration_response.registration_id(); - - FileUploadResponse upload_response; - transaction->UploadFile(&upload_response, registration_id); - - Entity file_entity; - file_entity.SetRole("File"); - file_entity.SetFileTransmissionId(registration_id, "test.txt"); - file_entity.SetFilePath("test.txt"); - - transaction->InsertEntity(&file_entity); - transaction->Execute(); - - auto cleanup_transaction(connection->CreateTransaction()); - cleanup_transaction->DeleteById(transaction->GetResultSet().At(0).GetId()); - cleanup_transaction->Execute(); -} - -TEST_F(test_file_transmission, file_download) { - const auto &connection = - caosdb::connection::ConnectionManager::GetDefaultConnection(); - - auto upload_transaction(connection->CreateTransaction()); - RegisterFileUploadResponse upload_registration_response; - - upload_transaction->RegisterUploadFile(&upload_registration_response); - ASSERT_EQ(upload_registration_response.status(), - RegistrationStatus::REGISTRATION_STATUS_ACCEPTED); - auto registration_id = upload_registration_response.registration_id(); - - FileUploadResponse upload_response; - upload_transaction->UploadFile(&upload_response, registration_id); - - Entity file_entity; - file_entity.SetRole("File"); - file_entity.SetFileTransmissionId(registration_id, "test.txt"); - file_entity.SetFilePath("test.txt"); - - upload_transaction->InsertEntity(&file_entity); - upload_transaction->Execute(); - - // Download by entity_id - auto download_transaction(connection->CreateTransaction()); - RegisterFileDownloadResponse download_registration_response; - RegisterFileDownloadRequest download_registration_request; - download_registration_request.add_files()->set_entity_id( - upload_transaction->GetResultSet().At(0).GetId()); - download_transaction->RegisterDownloadFile(download_registration_request, - &download_registration_response); - ASSERT_EQ(download_registration_response.status(), - RegistrationStatus::REGISTRATION_STATUS_ACCEPTED); - - FileDownloadResponse download_response; - download_transaction->DownloadFile(&download_response, - download_registration_response); - - EXPECT_EQ(download_response.chunk().data(), "this is some data"); - - // CLEANUP - auto cleanup_transaction(connection->CreateTransaction()); - cleanup_transaction->DeleteById( - upload_transaction->GetResultSet().At(0).GetId()); - cleanup_transaction->Execute(); -} - -} // namespace caosdb::transaction diff --git a/test/test_list_properties.cpp b/test/test_list_properties.cpp new file mode 100644 index 0000000000000000000000000000000000000000..83581bcc8438d513e44a5d46536d3000af923920 --- /dev/null +++ b/test/test_list_properties.cpp @@ -0,0 +1,114 @@ +/* + * This file is a part of the CaosDB Project. + * + * Copyright (C) 2021 Timm Fitschen <t.fitschen@indiscale.com> + * Copyright (C) 2021 IndiScale GmbH <info@indiscale.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ +#include "caosdb/connection.h" // for Connection, ConnectionManager +#include "caosdb/data_type.h" // for AtomicDataType +#include "caosdb/entity.h" // for Entity, Messages, Message +#include "caosdb/transaction.h" // for Entity, Transaction,... +#include "caosdb/transaction_status.h" // for TransactionStatus, StatusCode +#include "caosdb/value.h" // for value +#include <gtest/gtest-message.h> // for Message +#include <gtest/gtest-test-part.h> // for TestPartResult, SuiteApiResolver +#include <gtest/gtest_pred_impl.h> // for Test, EXPECT_EQ, AssertionResult +#include <iostream> +#include <memory> // for unique_ptr, allocator, __shar... +#include <string> // for string +#include <vector> // for vector + +namespace caosdb::entity { + +class test_list_properties : public ::testing::Test { +protected: + void SetUp() override {} + + void TearDown() override { + const auto &connection = + caosdb::connection::ConnectionManager::GetDefaultConnection(); + auto query_transaction(connection->CreateTransaction()); + query_transaction->Query("FIND ENTITY WITH id > 99"); + query_transaction->Execute(); + if (query_transaction->GetResultSet().size() > 0) { + auto delete_transaction(connection->CreateTransaction()); + for (const Entity &entity : query_transaction->GetResultSet()) { + delete_transaction->DeleteById(entity.GetId()); + } + delete_transaction->Execute(); + } + } +}; + +TEST_F(test_list_properties, insert_list_of_text) { + const auto &connection = + caosdb::connection::ConnectionManager::GetDefaultConnection(); + + auto insertion_prop(connection->CreateTransaction()); + + Entity abstract_list_property; + abstract_list_property.SetRole(Role::PROPERTY); + abstract_list_property.SetName("TestProp"); + abstract_list_property.SetDataType(DataType::ListOf(AtomicDataType::TEXT)); + abstract_list_property.SetValue( + std::vector<std::string>{"item1", "item2", "item3"}); + + insertion_prop->InsertEntity(&abstract_list_property); + std::cout << "response " << insertion_prop->ResponseToString(); + insertion_prop->Execute(); + EXPECT_TRUE(insertion_prop->GetStatus().IsTerminated()); + + auto insertion_rt(connection->CreateTransaction()); + + Property list_property; + list_property.SetId(insertion_prop->GetResultSet().at(0).GetId()); + list_property.SetValue(std::vector<std::string>{"item4", "item5", "item6"}); + + Entity entity; + entity.SetRole(Role::RECORD_TYPE); + entity.SetName("TestRT"); + entity.AppendProperty(list_property); + + insertion_rt->InsertEntity(&entity); + std::cout << "response " << insertion_rt->ResponseToString(); + insertion_rt->Execute(); + EXPECT_TRUE(insertion_rt->GetStatus().IsTerminated()); + EXPECT_FALSE(insertion_rt->GetStatus().IsError()); + + // retrieve and check again + auto retrieval(connection->CreateTransaction()); + retrieval->RetrieveById(insertion_rt->GetResultSet().at(0).GetId()); + retrieval->Execute(); + + EXPECT_TRUE(retrieval->GetStatus().IsTerminated()); + EXPECT_FALSE(retrieval->GetStatus().IsError()); + + const auto &same_entity = retrieval->GetResultSet().at(0); + const auto &data_type = same_entity.GetProperties().at(0).GetDataType(); + const auto &value = same_entity.GetProperties().at(0).GetValue(); + + EXPECT_TRUE(data_type.IsList()); + EXPECT_TRUE(data_type.AsList().IsListOfAtomic()); + EXPECT_EQ(data_type.AsList().GetAtomicDataType(), AtomicDataType::TEXT); + + EXPECT_TRUE(value.IsList()); + EXPECT_EQ(value.AsList().size(), 3); + EXPECT_TRUE(value.AsList().at(1).IsString()); + EXPECT_EQ(value.AsList().at(1).AsString(), "item6"); +} + +} // namespace caosdb::entity diff --git a/test/test_transaction.cpp b/test/test_transaction.cpp index a3182843d81520a91e8f4932bb1f023172a98d4a..0648c13af45ae098e20808cfece5a2290b9c6f66 100644 --- a/test/test_transaction.cpp +++ b/test/test_transaction.cpp @@ -19,6 +19,7 @@ * */ #include "caosdb/connection.h" // for Connection, ConnectionManager +#include "caosdb/data_type.h" // for AtomicDataType #include "caosdb/entity.h" // for Entity, Messages, Message #include "caosdb/file_transmission/file_reader.h" // for FileReader #include "caosdb/file_transmission/file_writer.h" // for FileWriter @@ -39,10 +40,13 @@ namespace fs = boost::filesystem; namespace caosdb::transaction { +using caosdb::entity::AtomicDataType; using caosdb::entity::Entity; +using caosdb::entity::Importance; using caosdb::entity::MessageCode; using caosdb::entity::Parent; using caosdb::entity::Property; +using caosdb::entity::Role; class test_transaction : public ::testing::Test { protected: @@ -53,6 +57,7 @@ protected: test_upload_file_1 = fs::path("test_upload_file_1_delete_me.dat"); test_download_file_1 = fs::path("test_download_file_1_delete_me.dat"); + // fill the file that shall be uploaded FileWriter writer(test_upload_file_1); std::string buffer(1024, 'c'); for (int i = 0; i < 8; i++) { @@ -61,9 +66,11 @@ protected: } void TearDown() override { + // delete files fs::remove(test_upload_file_1); fs::remove(test_download_file_1); + // delete all entities const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection(); auto query_transaction(connection->CreateTransaction()); @@ -79,30 +86,12 @@ protected: } }; -TEST_F(test_transaction, DISABLED_retrieve_manufacturer_by_id) { - const auto &connection = - caosdb::connection::ConnectionManager::GetDefaultConnection(); - - const auto *id = "107"; - const auto *role = "RecordType"; - const auto *name = "Manufacturer"; - const auto *description = "A generic manufacturer of all kinds of products"; - const auto *version = "0bea8f7b17f0130fa5701a6c3849b9f8bfa0651b"; - - auto transaction(connection->CreateTransaction()); - transaction->RetrieveById(id); - transaction->Execute(); - - const auto &result_set = transaction->GetResultSet(); - - const auto &entity = result_set.at(0); - EXPECT_EQ(id, entity.GetId()); - EXPECT_EQ(name, entity.GetName()); - EXPECT_EQ(role, entity.GetRole()); - EXPECT_EQ(description, entity.GetDescription()); - EXPECT_EQ(version, entity.GetVersionId()); -} - +/* + * Test the retrieval of a non-existing entity + * + * The transaction returns an error code and the entity has the appropriate + * error message + */ TEST_F(test_transaction, retrieve_non_existing) { const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection(); @@ -127,6 +116,12 @@ TEST_F(test_transaction, retrieve_non_existing) { MessageCode::ENTITY_DOES_NOT_EXIST); } +/* + * Testing the insertion of a basic entity + * Transaction should terminate without errors. + * Returned entity should have an id, no errors and a warning since no property + * is set. + */ TEST_F(test_transaction, insert_without_delete) { const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection(); @@ -134,7 +129,7 @@ TEST_F(test_transaction, insert_without_delete) { auto insert_transaction(connection->CreateTransaction()); Entity entity; - entity.SetRole("RecordType"); + entity.SetRole(Role::RECORD_TYPE); entity.SetName("RT1"); insert_transaction->InsertEntity(&entity); insert_transaction->ExecuteAsynchronously(); @@ -156,14 +151,20 @@ TEST_F(test_transaction, insert_without_delete) { MessageCode::ENTITY_HAS_NO_PROPERTIES); } +/* + * Test deletion of an entity + * Insert an entity first. + */ TEST_F(test_transaction, insert_delete) { + // same as in insert_without_delete + // until marked END SAME const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection(); auto insert_transaction(connection->CreateTransaction()); Entity entity; - entity.SetRole("RecordType"); + entity.SetRole(Role::RECORD_TYPE); entity.SetName("RT1"); insert_transaction->InsertEntity(&entity); insert_transaction->ExecuteAsynchronously(); @@ -177,12 +178,7 @@ TEST_F(test_transaction, insert_delete) { const auto &new_entity = insert_result_set.at(0); EXPECT_FALSE(new_entity.GetId().empty()); - EXPECT_FALSE(new_entity.HasErrors()); - // Should have a warning since it has no properties - EXPECT_TRUE(new_entity.HasWarnings()); - EXPECT_EQ(new_entity.GetWarnings().size(), 1); - EXPECT_EQ(new_entity.GetWarnings().at(0).GetCode(), - MessageCode::ENTITY_HAS_NO_PROPERTIES); + // END SAME auto delete_transaction(connection->CreateTransaction()); @@ -201,14 +197,20 @@ TEST_F(test_transaction, insert_delete) { EXPECT_FALSE(deleted_entity.HasErrors()); } +/* + * Insert a Record with a parent, retrieve and delete it again + */ TEST_F(test_transaction, insert_delete_with_parent) { + // same as in insert_without_delete + // until marked END SAME const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection(); auto insert_transaction(connection->CreateTransaction()); + // insert RT Entity rt; - rt.SetRole("RecordType"); + rt.SetRole(Role::RECORD_TYPE); rt.SetName("TestRT"); insert_transaction->InsertEntity(&rt); insert_transaction->ExecuteAsynchronously(); @@ -221,9 +223,11 @@ TEST_F(test_transaction, insert_delete_with_parent) { const auto &insert_result_set = insert_transaction->GetResultSet(); const auto &inserted_rt = insert_result_set.at(0); + // END SAME + // create Record with parent Entity rec; - rec.SetRole("Record"); + rec.SetRole(Role::RECORD); rec.SetName("TestRec"); Parent parent; @@ -231,6 +235,7 @@ TEST_F(test_transaction, insert_delete_with_parent) { parent.SetId(inserted_rt.GetId()); rec.AppendParent(parent); + // insert Record auto rec_transaction(connection->CreateTransaction()); rec_transaction->InsertEntity(&rec); rec_transaction->ExecuteAsynchronously(); @@ -246,6 +251,7 @@ TEST_F(test_transaction, insert_delete_with_parent) { EXPECT_FALSE(inserted_rec.GetId().empty()); + // retrieve inserted Record auto retrieve_transaction(connection->CreateTransaction()); retrieve_transaction->RetrieveById(inserted_rec.GetId()); @@ -259,11 +265,13 @@ TEST_F(test_transaction, insert_delete_with_parent) { const auto &retrieve_result_set = retrieve_transaction->GetResultSet(); const auto &retrieved_rec = retrieve_result_set.at(0); + // compare retrieved record with the one that was inserted EXPECT_EQ(retrieved_rec.GetName(), rec.GetName()); EXPECT_EQ(retrieved_rec.GetParents().size(), 1); EXPECT_EQ(retrieved_rec.GetParents().at(0).GetId(), inserted_rt.GetId()); EXPECT_EQ(retrieved_rec.GetParents().at(0).GetName(), rt.GetName()); + // delete the inserted record again auto rec_deletion(connection->CreateTransaction()); rec_deletion->DeleteById(retrieved_rec.GetId()); @@ -274,6 +282,7 @@ TEST_F(test_transaction, insert_delete_with_parent) { ASSERT_TRUE(rec_delete_status.IsTerminated()); ASSERT_FALSE(rec_delete_status.IsError()); + // delete the record type again auto rt_deletion(connection->CreateTransaction()); rt_deletion->DeleteById(inserted_rt.GetId()); @@ -285,15 +294,18 @@ TEST_F(test_transaction, insert_delete_with_parent) { ASSERT_FALSE(rt_delete_status.IsError()); } +/* + * insert a property, record type with that property and a record with it + */ TEST_F(test_transaction, insert_delete_with_property) { const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection(); // Create and insert property Entity prop_ent; - prop_ent.SetRole("Property"); + prop_ent.SetRole(Role::PROPERTY); prop_ent.SetName("TestProperty"); - prop_ent.SetDatatype("TEXT"); + prop_ent.SetDataType(AtomicDataType::TEXT); auto prop_insertion(connection->CreateTransaction()); prop_insertion->InsertEntity(&prop_ent); @@ -313,10 +325,10 @@ TEST_F(test_transaction, insert_delete_with_property) { Property prop_rt; prop_rt.SetName(prop_ent.GetName()); prop_rt.SetId(inserted_prop.GetId()); - prop_rt.SetImportance("SUGGESTED"); + prop_rt.SetImportance(Importance::SUGGESTED); Entity rt; - rt.SetRole("RecordType"); + rt.SetRole(Role::RECORD_TYPE); rt.SetName("TestRT"); rt.SetDescription("Some description"); rt.AppendProperty(prop_rt); @@ -355,7 +367,7 @@ TEST_F(test_transaction, insert_delete_with_property) { const auto &retrieved_prop_rt = retrieved_rt.GetProperties().at(0); EXPECT_EQ(retrieved_prop_rt.GetName(), prop_ent.GetName()); EXPECT_EQ(retrieved_prop_rt.GetId(), inserted_prop.GetId()); - EXPECT_EQ(retrieved_prop_rt.GetDatatype(), prop_ent.GetDatatype()); + EXPECT_EQ(retrieved_prop_rt.GetDataType(), prop_ent.GetDataType()); EXPECT_EQ(retrieved_prop_rt.GetImportance(), prop_rt.GetImportance()); // create and insert record of the above record type with a property @@ -367,11 +379,11 @@ TEST_F(test_transaction, insert_delete_with_property) { Property prop_rec; prop_rec.SetName(prop_ent.GetName()); prop_rec.SetId(inserted_prop.GetId()); - prop_rec.SetValue("Test"); + prop_rec.SetValue(std::string("Test")); Entity rec; rec.SetName("TestRec"); - rec.SetRole("Record"); + rec.SetRole(Role::RECORD); rec.AppendParent(parent); rec.AppendProperty(prop_rec); @@ -389,7 +401,7 @@ TEST_F(test_transaction, insert_delete_with_property) { const auto &inserted_rec = rec_result_set.at(0); EXPECT_FALSE(inserted_rec.GetId().empty()); - // Retrieve the record and verify paretn and property + // Retrieve the record and verify parent and property auto rec_retrieval(connection->CreateTransaction()); rec_retrieval->RetrieveById(inserted_rec.GetId()); rec_retrieval->ExecuteAsynchronously(); @@ -414,10 +426,13 @@ TEST_F(test_transaction, insert_delete_with_property) { const auto &retrieved_prop_rec = retrieved_rec.GetProperties().at(0); EXPECT_EQ(retrieved_prop_rec.GetName(), prop_ent.GetName()); EXPECT_EQ(retrieved_prop_rec.GetId(), inserted_prop.GetId()); - EXPECT_EQ(retrieved_prop_rec.GetDatatype(), prop_ent.GetDatatype()); + EXPECT_EQ(retrieved_prop_rec.GetDataType(), prop_ent.GetDataType()); EXPECT_EQ(retrieved_prop_rec.GetValue(), prop_rec.GetValue()); } +/* + * test retrieving multiple entities at once + */ TEST_F(test_transaction, test_multi_retrieve) { const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection(); @@ -449,6 +464,9 @@ TEST_F(test_transaction, test_multi_retrieve) { MessageCode::ENTITY_DOES_NOT_EXIST); } +/* + * test insert, then update and then delete a RecordType + */ TEST_F(test_transaction, insert_update_delete) { const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection(); @@ -457,7 +475,7 @@ TEST_F(test_transaction, insert_update_delete) { auto insert_transaction(connection->CreateTransaction()); Entity entity; - entity.SetRole("RecordType"); + entity.SetRole(Role::RECORD_TYPE); entity.SetName("RT1"); insert_transaction->InsertEntity(&entity); insert_transaction->ExecuteAsynchronously(); @@ -514,6 +532,9 @@ TEST_F(test_transaction, insert_update_delete) { EXPECT_FALSE(deleted_entity.HasErrors()); } +/* + * test insert a RecordType and then submit a find and a count query + */ TEST_F(test_transaction, test_query) { const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection(); @@ -521,7 +542,7 @@ TEST_F(test_transaction, test_query) { auto insert_transaction(connection->CreateTransaction()); Entity entity; - entity.SetRole("RecordType"); + entity.SetRole(Role::RECORD_TYPE); entity.SetName("RT1"); insert_transaction->InsertEntity(&entity); insert_transaction->ExecuteAsynchronously(); @@ -556,13 +577,17 @@ TEST_F(test_transaction, test_query) { EXPECT_EQ(count_query_trans->GetCountResult(), 1); } +/* + * insert three recordtypes and the submit multiple queries in different + * combinations + */ TEST_F(test_transaction, test_query_with_retrieve) { const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection(); // rt1 Entity rt1; - rt1.SetRole("RecordType"); + rt1.SetRole(Role::RECORD_TYPE); rt1.SetName("TestRT1"); auto insert_rt1_transaction(connection->CreateTransaction()); @@ -582,7 +607,7 @@ TEST_F(test_transaction, test_query_with_retrieve) { // rt2 Entity rt2; - rt2.SetRole("RecordType"); + rt2.SetRole(Role::RECORD_TYPE); rt2.SetName("TestRT2"); auto insert_rt2_transaction(connection->CreateTransaction()); @@ -602,7 +627,7 @@ TEST_F(test_transaction, test_query_with_retrieve) { // rt3 Entity rt3; - rt3.SetRole("RecordType"); + rt3.SetRole(Role::RECORD_TYPE); rt3.SetName("TestRT3"); auto insert_rt3_transaction(connection->CreateTransaction()); @@ -668,12 +693,15 @@ TEST_F(test_transaction, test_query_with_retrieve) { EXPECT_EQ(count_and_retrieve->GetCountResult(), 3); } +/* + * create a file object and upload it + */ TEST_F(test_transaction, test_file_upload) { const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection(); Entity file; - file.SetRole("File"); + file.SetRole(Role::FILE); file.SetFilePath("test.txt"); file.SetLocalPath(test_upload_file_1); @@ -702,12 +730,15 @@ TEST_F(test_transaction, test_file_upload) { EXPECT_EQ(count_query->GetCountResult(), 1); } +/* + * create a file object, upload and then download it + */ TEST_F(test_transaction, test_file_up_n_download) { const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection(); Entity file; - file.SetRole("File"); + file.SetRole(Role::FILE); file.SetFilePath("test.txt"); file.SetLocalPath(test_upload_file_1); @@ -745,4 +776,131 @@ TEST_F(test_transaction, test_file_up_n_download) { } } +/* + * Test a small worklfow + */ +TEST_F(test_transaction, test_full_workflow) { + const auto &connection = + caosdb::connection::ConnectionManager::GetDefaultConnection(); + + // ###### Create Data Model ###### + Entity dataRT; + dataRT.SetRole(Role::RECORD_TYPE); + dataRT.SetName("DataRT"); + + Entity voltage; + voltage.SetRole(Role::PROPERTY); + voltage.SetName("voltage"); + voltage.SetUnit("V"); + voltage.SetDataType(AtomicDataType::DOUBLE); + + Entity notes; + notes.SetRole(Role::PROPERTY); + notes.SetName("notes"); + notes.SetDataType(AtomicDataType::TEXT); + + Entity participants; + participants.SetRole(Role::PROPERTY); + participants.SetName("participants"); + participants.SetDataType(AtomicDataType::INTEGER); + // participants.SetDataType(ListDataType::); + + Entity success; + success.SetRole(Role::PROPERTY); + success.SetName("success"); + success.SetDataType(AtomicDataType::BOOLEAN); + + Entity experiment; + experiment.SetRole(Role::RECORD_TYPE); + experiment.SetName("Experiment"); + // TODO(henrik): creating this extra Property (additionally to the Entity + // above) is VERY clumsy + Property volt_for_rt; + volt_for_rt.SetName(voltage.GetName()); + volt_for_rt.SetImportance(Importance::RECOMMENDED); + experiment.AppendProperty(volt_for_rt); + Property notes_for_rt2; + notes_for_rt2.SetName(notes.GetName()); + notes_for_rt2.SetImportance(Importance::RECOMMENDED); + experiment.AppendProperty(notes_for_rt2); + Property part_for_rt3; + part_for_rt3.SetName(participants.GetName()); + part_for_rt3.SetImportance(Importance::SUGGESTED); + experiment.AppendProperty(part_for_rt3); + Property succ_for_rt; + succ_for_rt.SetName(success.GetName()); + succ_for_rt.SetImportance(Importance::SUGGESTED); + experiment.AppendProperty(succ_for_rt); + + auto insert_transaction(connection->CreateTransaction()); + insert_transaction->InsertEntity(&dataRT); + auto insert_status = insert_transaction->Execute(); + const auto &insert_results = insert_transaction->GetResultSet(); + const auto &inserted_ent = insert_results.at(0); + ASSERT_FALSE(inserted_ent.GetId().empty()); + ASSERT_FALSE(inserted_ent.HasErrors()); + + insert_transaction = connection->CreateTransaction(); + insert_transaction->InsertEntity(&voltage); + insert_status = insert_transaction->Execute(); + insert_transaction = connection->CreateTransaction(); + insert_transaction->InsertEntity(¬es); + insert_status = insert_transaction->Execute(); + insert_transaction = connection->CreateTransaction(); + insert_transaction->InsertEntity(&participants); + insert_status = insert_transaction->Execute(); + insert_transaction = connection->CreateTransaction(); + insert_transaction->InsertEntity(&success); + insert_status = insert_transaction->Execute(); + insert_transaction = connection->CreateTransaction(); + insert_transaction->InsertEntity(&experiment); + insert_status = insert_transaction->Execute(); + + auto retr_transaction(connection->CreateTransaction()); + retr_transaction->Query("FIND Experiment"); + retr_transaction->Execute(); + EXPECT_EQ(retr_transaction->GetResultSet().size(), 1); + + Parent experiment_parent; + experiment_parent.SetName("Experiment"); + + for (int i = 0; i < 8; i++) { + Entity experiment_rec; + experiment_rec.SetRole(Role::RECORD); + experiment_rec.AppendParent(experiment_parent); + volt_for_rt.SetValue(1.6); + experiment_rec.AppendProperty(volt_for_rt); + notes_for_rt2.SetValue("This is important!"); + experiment_rec.AppendProperty(notes_for_rt2); + part_for_rt3.SetValue(static_cast<int64_t>(6)); + experiment_rec.AppendProperty(part_for_rt3); + succ_for_rt.SetValue(true); + experiment_rec.AppendProperty(succ_for_rt); + auto rec_insert_transaction(connection->CreateTransaction()); + rec_insert_transaction->InsertEntity(&experiment_rec); + std::cout << "before ..." << std::endl; + insert_status = rec_insert_transaction->Execute(); + std::cout << "after ..." << std::endl; + } + + retr_transaction = connection->CreateTransaction(); + retr_transaction->Query("FIND Record Experiment"); + retr_transaction->Execute(); + EXPECT_EQ(retr_transaction->GetResultSet().size(), 8); + + auto to_be_updated = retr_transaction->GetResultSet().at(0); + // TODO(henrik) using the index for deletion is very inconvenient + to_be_updated.RemoveProperty(0); + to_be_updated.SetName("changedone"); + + auto update_transaction(connection->CreateTransaction()); + update_transaction->UpdateEntity(&to_be_updated); + update_transaction->Execute(); + + retr_transaction = connection->CreateTransaction(); + retr_transaction->Query("FIND Record Experiment with name=changedone"); + retr_transaction->Execute(); + EXPECT_EQ(retr_transaction->GetResultSet().size(), 1); +} + } // namespace caosdb::transaction