Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • caosdb/src/caosdb-cpplib
1 result
Show changes
Showing
with 780 additions and 861 deletions
......@@ -48,11 +48,9 @@ BOOST_LOG_GLOBAL_LOGGER_INIT(logger, boost_logger_class) {
boost_logger_class lg;
return lg;
}
LoggingConfiguration::LoggingConfiguration(int level)
: LevelConfiguration(level) {}
LoggingConfiguration::LoggingConfiguration(int level) : LevelConfiguration(level) {}
auto LoggingConfiguration::AddSink(
const std::shared_ptr<SinkConfiguration> &sink) -> void {
auto LoggingConfiguration::AddSink(const std::shared_ptr<SinkConfiguration> &sink) -> void {
this->sinks.push_back(sink);
}
......@@ -64,14 +62,10 @@ auto LoggingConfiguration::GetSinks() const
SinkConfiguration::SinkConfiguration(std::string name, int level)
: LevelConfiguration(level), name(std::move(name)) {}
[[nodiscard]] auto SinkConfiguration::GetName() const -> const std::string & {
return this->name;
}
[[nodiscard]] auto SinkConfiguration::GetName() const -> const std::string & { return this->name; }
auto SinkConfiguration::Configure(boost::log::settings &settings) const
-> void {
CAOSDB_LOG_TRACE(logger_name)
<< "Enter SinkConfiguration::Configure(&settings)";
auto SinkConfiguration::Configure(boost::log::settings &settings) const -> void {
CAOSDB_LOG_TRACE(logger_name) << "Enter SinkConfiguration::Configure(&settings)";
auto sink = "Sinks." + GetName();
settings[sink]["Destination"] = GetDestination();
settings[sink]["Filter"] = "%Severity% >= " + std::to_string(GetLevel());
......@@ -79,31 +73,24 @@ auto SinkConfiguration::Configure(boost::log::settings &settings) const
settings[sink]["Format"] = "[%TimeStamp%][%Severity%] %Channel% - %Message%";
}
ConsoleSinkConfiguration::ConsoleSinkConfiguration(const std::string &name,
int level)
ConsoleSinkConfiguration::ConsoleSinkConfiguration(const std::string &name, int level)
: SinkConfiguration(name, level) {}
[[nodiscard]] auto ConsoleSinkConfiguration::GetDestination() const
-> const std::string & {
CAOSDB_LOG_TRACE(logger_name)
<< "Enter ConsoleSinkConfiguration::GetDestination()";
[[nodiscard]] auto ConsoleSinkConfiguration::GetDestination() const -> const std::string & {
CAOSDB_LOG_TRACE(logger_name) << "Enter ConsoleSinkConfiguration::GetDestination()";
return this->destination;
}
auto ConsoleSinkConfiguration::Configure(boost::log::settings &settings) const
-> void {
CAOSDB_LOG_TRACE(logger_name)
<< "Enter ConsoleSinkConfiguration::Configure(&settings)";
auto ConsoleSinkConfiguration::Configure(boost::log::settings &settings) const -> void {
CAOSDB_LOG_TRACE(logger_name) << "Enter ConsoleSinkConfiguration::Configure(&settings)";
sink_configuration::Configure(settings);
}
FileSinkConfiguration::FileSinkConfiguration(const std::string &name, int level)
: SinkConfiguration(name, level) {}
[[nodiscard]] auto FileSinkConfiguration::GetDestination() const
-> const std::string & {
CAOSDB_LOG_TRACE(logger_name)
<< "Enter FileSinkConfiguration::GetDestination()";
[[nodiscard]] auto FileSinkConfiguration::GetDestination() const -> const std::string & {
CAOSDB_LOG_TRACE(logger_name) << "Enter FileSinkConfiguration::GetDestination()";
return this->destination;
}
......@@ -111,20 +98,16 @@ auto FileSinkConfiguration::SetDirectory(const std::string &directory) -> void {
this->directory = std::string(directory);
}
auto FileSinkConfiguration::Configure(boost::log::settings &settings) const
-> void {
CAOSDB_LOG_TRACE(logger_name)
<< "Enter FileSinkConfiguration::Configure(&settings)";
auto FileSinkConfiguration::Configure(boost::log::settings &settings) const -> void {
CAOSDB_LOG_TRACE(logger_name) << "Enter FileSinkConfiguration::Configure(&settings)";
sink_configuration::Configure(settings);
settings["Sink." + GetName() + ".Target"] = this->directory;
}
SyslogSinkConfiguration::SyslogSinkConfiguration(const std::string &name,
int level)
SyslogSinkConfiguration::SyslogSinkConfiguration(const std::string &name, int level)
: SinkConfiguration(name, level) {}
[[nodiscard]] auto SyslogSinkConfiguration::GetDestination() const
-> const std::string & {
[[nodiscard]] auto SyslogSinkConfiguration::GetDestination() const -> const std::string & {
return this->destination;
}
......@@ -137,8 +120,7 @@ auto initialize_logging_defaults() -> int {
// now set everything up
const static std::vector<std::shared_ptr<SinkConfiguration>> default_sinks = {
std::make_shared<ConsoleSinkConfiguration>("DEFAULT_SINK_1",
CAOSDB_DEFAULT_LOG_LEVEL)};
std::make_shared<ConsoleSinkConfiguration>("DEFAULT_SINK_1", CAOSDB_DEFAULT_LOG_LEVEL)};
boost::log::settings default_settings;
......@@ -150,8 +132,7 @@ auto initialize_logging_defaults() -> int {
boost::log::init_from_settings(default_settings);
auto core = boost::log::core::get();
core->add_global_attribute("TimeStamp",
boost::log::attributes::local_clock());
core->add_global_attribute("TimeStamp", boost::log::attributes::local_clock());
CAOSDB_LOG_DEBUG(logger_name) << "Initialized default settings.";
......@@ -185,39 +166,27 @@ auto initialize_logging(const LoggingConfiguration &configuration) -> void {
}
void caosdb_log_fatal(const char *channel, const char *msg) {
BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), channel,
CAOSDB_LOG_LEVEL_FATAL)
<< msg;
BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), channel, CAOSDB_LOG_LEVEL_FATAL) << msg;
}
void caosdb_log_error(const char *channel, const char *msg) {
BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), channel,
CAOSDB_LOG_LEVEL_ERROR)
<< msg;
BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), channel, CAOSDB_LOG_LEVEL_ERROR) << msg;
}
void caosdb_log_warn(const char *channel, const char *msg) {
BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), channel,
CAOSDB_LOG_LEVEL_WARN)
<< msg;
BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), channel, CAOSDB_LOG_LEVEL_WARN) << msg;
}
void caosdb_log_info(const char *channel, const char *msg) {
BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), channel,
CAOSDB_LOG_LEVEL_INFO)
<< msg;
BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), channel, CAOSDB_LOG_LEVEL_INFO) << msg;
}
void caosdb_log_debug(const char *channel, const char *msg) {
BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), channel,
CAOSDB_LOG_LEVEL_DEBUG)
<< msg;
BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), channel, CAOSDB_LOG_LEVEL_DEBUG) << msg;
}
void caosdb_log_trace(const char *channel, const char *msg) {
BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), channel,
CAOSDB_LOG_LEVEL_TRACE)
<< msg;
BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), channel, CAOSDB_LOG_LEVEL_TRACE) << msg;
}
} // namespace caosdb::logging
......@@ -18,22 +18,22 @@
*
*/
#include "caosdb/transaction.h"
#include "caosdb/entity/v1alpha1/main.grpc.pb.h" // for EntityTransac...
#include "caosdb/entity/v1alpha1/main.pb.h" // for TransactionRe...
#include "caosdb/file_transmission/download_request_handler.h" // Download...
#include "caosdb/file_transmission/file_reader.h" // for path
#include "caosdb/entity/v1alpha1/main.grpc.pb.h" // for EntityTransac...
#include "caosdb/entity/v1alpha1/main.pb.h" // for TransactionRe...
#include "caosdb/file_transmission/download_request_handler.h" // Download...
#include "caosdb/file_transmission/file_reader.h" // for path
#include "caosdb/file_transmission/register_file_upload_handler.h" // for RegisterFileUploadHandler
#include "caosdb/file_transmission/upload_request_handler.h" // Upload...
#include "caosdb/logging.h" // for CAOSDB_LOG_FATAL
#include "caosdb/status_code.h" // for StatusCode
#include "caosdb/transaction_handler.h" // for EntityTransactionHandler
#include <algorithm> // for max
#include <boost/filesystem/path.hpp> // for operator<<, path
#include <boost/log/core/record.hpp> // for record
#include <boost/log/detail/attachable_sstream_buf.hpp> // for basic_ostring...
#include <boost/log/sources/record_ostream.hpp> // for basic_record_...
#include <boost/preprocessor/seq/limits/enum_256.hpp> // for BOOST_PP_SEQ_...
#include <boost/preprocessor/seq/limits/size_256.hpp> // for BOOST_PP_SEQ_...
#include "caosdb/file_transmission/upload_request_handler.h" // Upload...
#include "caosdb/logging.h" // for CAOSDB_LOG_FATAL
#include "caosdb/status_code.h" // for StatusCode
#include "caosdb/transaction_handler.h" // for EntityTransactionHandler
#include <algorithm> // for max
#include <boost/filesystem/path.hpp> // for operator<<, path
#include <boost/log/core/record.hpp> // for record
#include <boost/log/detail/attachable_sstream_buf.hpp> // for basic_ostring...
#include <boost/log/sources/record_ostream.hpp> // for basic_record_...
#include <boost/preprocessor/seq/limits/enum_256.hpp> // for BOOST_PP_SEQ_...
#include <boost/preprocessor/seq/limits/size_256.hpp> // for BOOST_PP_SEQ_...
// IWYU pragma: no_include <bits/exception.h>
#include <exception> // IWYU pragma: keep
#include <google/protobuf/arena.h> // for Arena
......@@ -52,14 +52,11 @@ namespace caosdb {
auto get_status_description(int code) -> const std::string & {
static const std::string MISSING_DESCRIPTION = "MISSING DESCRIPTION";
static const std::map<int, std::string> descriptions = {
{StatusCode::INITIAL,
"The transaction has just been intialized. It has not been executed yet "
"and clients can still change it and add sub-transactions."},
{StatusCode::GO_ON,
"The transaction has a transaction_type yet and clients may add matching "
"sub-transaction or execute it right-away."},
{StatusCode::READY,
"The transaction is ready for execution and cannot be changed anymore."},
{StatusCode::INITIAL, "The transaction has just been intialized. It has not been executed yet "
"and clients can still change it and add sub-transactions."},
{StatusCode::GO_ON, "The transaction has a transaction_type yet and clients may add matching "
"sub-transaction or execute it right-away."},
{StatusCode::READY, "The transaction is ready for execution and cannot be changed anymore."},
{StatusCode::EXECUTING, "The transaction is currently being executed."},
{StatusCode::SUCCESS, "The action was successful"},
{StatusCode::CONNECTION_ERROR,
......@@ -71,8 +68,7 @@ auto get_status_description(int code) -> const std::string & {
{StatusCode::GENERIC_RPC_ERROR,
"The attempt to execute this transaction was not successful because an "
"error occured in the transport or RPC protocol layer."},
{StatusCode::GENERIC_ERROR,
"An error occured. Please review the logs for more information."},
{StatusCode::GENERIC_ERROR, "An error occured. Please review the logs for more information."},
{StatusCode::GENERIC_TRANSACTION_ERROR,
"The transaction terminated unsuccessfully with transaction errors."},
{StatusCode::CONFIGURATION_ERROR,
......@@ -93,10 +89,8 @@ auto get_status_description(int code) -> const std::string & {
{StatusCode::PATH_IS_A_DIRECTORY, "The given path is a directory."},
{StatusCode::FILE_DOES_NOT_EXIST_LOCALLY,
"The file does not not exist in the local file system."},
{StatusCode::FILE_DOWNLOAD_ERROR,
"The transaction failed during the download of the files"},
{StatusCode::FILE_UPLOAD_ERROR,
"The transaction failed during the upload of the files"},
{StatusCode::FILE_DOWNLOAD_ERROR, "The transaction failed during the download of the files"},
{StatusCode::FILE_UPLOAD_ERROR, "The transaction failed during the upload of the files"},
{StatusCode::UNSUPPORTED_FEATURE,
"This feature is not available in the this client implementation."},
{StatusCode::EXTERN_C_ASSIGNMENT_ERROR,
......@@ -122,8 +116,7 @@ using caosdb::entity::v1alpha1::MultiTransactionRequest;
using caosdb::entity::v1alpha1::MultiTransactionResponse;
using TransactionResponseCase =
caosdb::entity::v1alpha1::TransactionResponse::TransactionResponseCase;
using RetrieveResponseCase =
caosdb::entity::v1alpha1::RetrieveResponse::RetrieveResponseCase;
using RetrieveResponseCase = caosdb::entity::v1alpha1::RetrieveResponse::RetrieveResponseCase;
using ProtoEntity = caosdb::entity::v1alpha1::Entity;
using google::protobuf::Arena;
using NextStatus = grpc::CompletionQueue::NextStatus;
......@@ -151,20 +144,15 @@ auto ResultSet::iterator::operator!=(const iterator &rhs) const -> bool {
return this->current_index != rhs.current_index;
}
auto ResultSet::begin() const -> ResultSet::iterator {
return ResultSet::iterator(this, 0);
}
auto ResultSet::begin() const -> ResultSet::iterator { return ResultSet::iterator(this, 0); }
auto ResultSet::end() const -> ResultSet::iterator {
return ResultSet::iterator(this, size());
}
auto ResultSet::end() const -> ResultSet::iterator { return ResultSet::iterator(this, size()); }
MultiResultSet::MultiResultSet(std::vector<std::unique_ptr<Entity>> result_set)
: AbstractMultiResultSet(std::move(result_set)) {}
Transaction::Transaction(
std::shared_ptr<EntityTransactionService::Stub> entity_service,
std::shared_ptr<FileTransmissionService::Stub> file_service)
Transaction::Transaction(std::shared_ptr<EntityTransactionService::Stub> entity_service,
std::shared_ptr<FileTransmissionService::Stub> file_service)
: request(Arena::CreateMessage<MultiTransactionRequest>(GetArena())),
response(Arena::CreateMessage<MultiTransactionResponse>(GetArena())) {
this->entity_service = std::move(entity_service);
......@@ -182,12 +170,12 @@ auto Transaction::RetrieveById(const std::string &id) noexcept -> StatusCode {
return this->status.GetCode();
}
auto Transaction::RetrieveAndDownloadFilesById(
const std::string &id, const std::string &local_path) noexcept -> StatusCode {
auto Transaction::RetrieveAndDownloadFilesById(const std::string &id,
const std::string &local_path) noexcept
-> StatusCode {
ASSERT_CAN_ADD_RETRIEVAL
auto *retrieve_request =
this->request->add_requests()->mutable_retrieve_request();
auto *retrieve_request = this->request->add_requests()->mutable_retrieve_request();
retrieve_request->set_id(id);
retrieve_request->set_register_file_download(true);
......@@ -223,9 +211,8 @@ auto Transaction::DeleteById(const std::string &id) noexcept -> StatusCode {
auto Transaction::InsertEntity(Entity *entity) noexcept -> StatusCode {
ASSERT_CAN_ADD_INSERTION
auto *entity_request = this->request->add_requests()
->mutable_insert_request()
->mutable_entity_request();
auto *entity_request =
this->request->add_requests()->mutable_insert_request()->mutable_entity_request();
auto *proto_entity = entity_request->mutable_entity();
// copy the original entity for the transaction
......@@ -242,9 +229,8 @@ auto Transaction::InsertEntity(Entity *entity) noexcept -> StatusCode {
auto Transaction::UpdateEntity(Entity *entity) noexcept -> StatusCode {
ASSERT_CAN_ADD_UPDATE
auto *entity_request = this->request->add_requests()
->mutable_update_request()
->mutable_entity_request();
auto *entity_request =
this->request->add_requests()->mutable_update_request()->mutable_entity_request();
auto *proto_entity = entity_request->mutable_entity();
entity->CopyTo(proto_entity);
......@@ -259,8 +245,8 @@ auto Transaction::UpdateEntity(Entity *entity) noexcept -> StatusCode {
auto Transaction::Execute() -> TransactionStatus {
auto status_code = ExecuteAsynchronously();
TransactionStatus::ThrowExceptionIfError(
status_code, caosdb::get_status_description(status_code));
TransactionStatus::ThrowExceptionIfError(status_code,
caosdb::get_status_description(status_code));
auto status = WaitForIt();
status.ThrowExceptionIfError();
return status;
......@@ -268,8 +254,7 @@ auto Transaction::Execute() -> TransactionStatus {
// TODO(tf) This has apparently a cognitive complexity of 39>25 (threshold).
auto Transaction::ExecuteAsynchronously() noexcept -> StatusCode { // NOLINT
if (!IsStatus(TransactionStatus::READY()) &&
!IsStatus(TransactionStatus::GO_ON())) {
if (!IsStatus(TransactionStatus::READY()) && !IsStatus(TransactionStatus::GO_ON())) {
return StatusCode::TRANSACTION_STATUS_ERROR;
}
switch (this->transaction_type) {
......@@ -292,21 +277,17 @@ auto Transaction::ExecuteAsynchronously() noexcept -> StatusCode { // NOLINT
// upload files first
if (!upload_files.empty()) {
CAOSDB_LOG_INFO(logger_name)
<< "Number of files to be uploaded: " << upload_files.size();
CAOSDB_LOG_INFO(logger_name) << "Number of files to be uploaded: " << upload_files.size();
auto *registration_request =
Arena::CreateMessage<RegisterFileUploadRequest>(GetArena());
auto *registration_response =
Arena::CreateMessage<RegisterFileUploadResponse>(GetArena());
auto *registration_request = Arena::CreateMessage<RegisterFileUploadRequest>(GetArena());
auto *registration_response = Arena::CreateMessage<RegisterFileUploadResponse>(GetArena());
handler_ = std::make_unique<RegisterFileUploadHandler>(
&handler_, file_service.get(), &completion_queue, registration_request,
registration_response);
handler_ =
std::make_unique<RegisterFileUploadHandler>(&handler_, file_service.get(), &completion_queue,
registration_request, registration_response);
this->status = ProcessCalls();
if (registration_response->status() !=
RegistrationStatus::REGISTRATION_STATUS_ACCEPTED) {
if (registration_response->status() != RegistrationStatus::REGISTRATION_STATUS_ACCEPTED) {
this->status = TransactionStatus::FILE_UPLOAD_ERROR();
return StatusCode::EXECUTING;
}
......@@ -314,10 +295,9 @@ auto Transaction::ExecuteAsynchronously() noexcept -> StatusCode { // NOLINT
for (auto &file_descriptor : upload_files) {
file_descriptor.file_transmission_id->set_registration_id(
registration_response->registration_id());
CAOSDB_LOG_INFO(logger_name)
<< "Uploading " << file_descriptor.local_path;
handler_ = std::make_unique<UploadRequestHandler>(
&handler_, file_service.get(), &completion_queue, file_descriptor);
CAOSDB_LOG_INFO(logger_name) << "Uploading " << file_descriptor.local_path;
handler_ = std::make_unique<UploadRequestHandler>(&handler_, file_service.get(),
&completion_queue, file_descriptor);
this->status = ProcessCalls();
if (this->status.GetCode() != StatusCode::EXECUTING) {
return StatusCode::EXECUTING;
......@@ -326,8 +306,8 @@ auto Transaction::ExecuteAsynchronously() noexcept -> StatusCode { // NOLINT
}
CAOSDB_LOG_DEBUG(logger_name) << "RPC Request: " << RequestToString();
handler_ = std::make_unique<EntityTransactionHandler>(
&handler_, entity_service.get(), &completion_queue, request, response);
handler_ = std::make_unique<EntityTransactionHandler>(&handler_, entity_service.get(),
&completion_queue, request, response);
this->status = ProcessCalls();
if (this->status.GetCode() != StatusCode::EXECUTING) {
return StatusCode::EXECUTING;
......@@ -337,16 +317,12 @@ auto Transaction::ExecuteAsynchronously() noexcept -> StatusCode { // NOLINT
if (status.GetCode() == StatusCode::EXECUTING && !download_files.empty()) {
// run over all retrieved entities and get the download_id
for (auto sub_response : *(response->mutable_responses())) {
if (sub_response.transaction_response_case() ==
TransactionResponseCase::kRetrieveResponse) {
if (sub_response.retrieve_response()
.entity_response()
.has_download_id()) {
if (sub_response.transaction_response_case() == TransactionResponseCase::kRetrieveResponse) {
if (sub_response.retrieve_response().entity_response().has_download_id()) {
auto *entity_response =
sub_response.mutable_retrieve_response()->mutable_entity_response();
auto entity_id = entity_response->entity().id();
download_files[entity_id].file_transmission_id =
entity_response->release_download_id();
download_files[entity_id].file_transmission_id = entity_response->release_download_id();
// TODO(tf) handle error
}
}
......@@ -354,11 +330,10 @@ auto Transaction::ExecuteAsynchronously() noexcept -> StatusCode { // NOLINT
for (const auto &item : download_files) {
auto file_descriptor(item.second);
CAOSDB_LOG_INFO(logger_name)
<< "Downloading " << file_descriptor.local_path;
CAOSDB_LOG_INFO(logger_name) << "Downloading " << file_descriptor.local_path;
handler_ = std::make_unique<DownloadRequestHandler>(
&handler_, file_service.get(), &completion_queue, file_descriptor);
handler_ = std::make_unique<DownloadRequestHandler>(&handler_, file_service.get(),
&completion_queue, file_descriptor);
this->status = ProcessCalls();
if (this->status.GetCode() != StatusCode::EXECUTING) {
return StatusCode::EXECUTING;
......@@ -386,8 +361,7 @@ auto Transaction::WaitForIt() const noexcept -> TransactionStatus { // NOLINT
switch (retrieve_response->retrieve_response_case()) {
case RetrieveResponseCase::kEntityResponse: {
auto *retrieve_entity_response =
retrieve_response->release_entity_response();
auto *retrieve_entity_response = retrieve_response->release_entity_response();
result = std::make_unique<Entity>(retrieve_entity_response);
} break;
case RetrieveResponseCase::kSelectResult: {
......@@ -418,26 +392,22 @@ auto Transaction::WaitForIt() const noexcept -> TransactionStatus { // NOLINT
}
case TransactionResponseCase::kInsertResponse: {
auto *inserted_id_response =
sub_response.mutable_insert_response()->release_id_response();
auto *inserted_id_response = sub_response.mutable_insert_response()->release_id_response();
result = std::make_unique<Entity>(inserted_id_response);
break;
}
case TransactionResponseCase::kDeleteResponse: {
auto *deleted_id_response =
sub_response.mutable_delete_response()->release_id_response();
auto *deleted_id_response = sub_response.mutable_delete_response()->release_id_response();
result = std::make_unique<Entity>(deleted_id_response);
break;
}
case TransactionResponseCase::kUpdateResponse: {
auto *updated_id_response =
sub_response.mutable_update_response()->release_id_response();
auto *updated_id_response = sub_response.mutable_update_response()->release_id_response();
result = std::make_unique<Entity>(updated_id_response);
break;
}
default:
CAOSDB_LOG_FATAL(logger_name)
<< "Received invalid TransactionResponseCase.";
CAOSDB_LOG_FATAL(logger_name) << "Received invalid TransactionResponseCase.";
break;
}
if (result != nullptr) {
......@@ -459,8 +429,7 @@ auto Transaction::WaitForIt() const noexcept -> TransactionStatus { // NOLINT
this->result_set = std::make_unique<MultiResultSet>(std::move(entities));
if (set_error) {
this->status = TransactionStatus::TRANSACTION_ERROR(
"The request terminated with errors.");
this->status = TransactionStatus::TRANSACTION_ERROR("The request terminated with errors.");
}
return this->status;
......@@ -495,8 +464,7 @@ auto Transaction::ProcessCalls() -> TransactionStatus {
}
} break;
case NextStatus::SHUTDOWN: {
CAOSDB_LOG_ERROR(logger_name)
<< "Notification queue has been shut down unexpectedly.";
CAOSDB_LOG_ERROR(logger_name) << "Notification queue has been shut down unexpectedly.";
result = handler_->GetStatus();
handler_.reset();
return result;
......@@ -505,8 +473,7 @@ auto Transaction::ProcessCalls() -> TransactionStatus {
CAOSDB_LOG_DEBUG(logger_name) << "Timeout, waiting...";
} break;
default:
CAOSDB_LOG_FATAL(logger_name)
<< "Got an invalid NextStatus from CompletionQueue.";
CAOSDB_LOG_FATAL(logger_name) << "Got an invalid NextStatus from CompletionQueue.";
result = handler_->GetStatus();
handler_.reset();
return result;
......
......@@ -13,28 +13,26 @@
namespace caosdb::transaction {
EntityTransactionHandler::EntityTransactionHandler(
HandlerTag tag, EntityTransactionService::Stub *stub,
grpc::CompletionQueue *completion_queue, MultiTransactionRequest *request,
MultiTransactionResponse *response)
: UnaryRpcHandler(completion_queue), tag_(tag), stub_(stub),
request_(request), response_(response) {}
EntityTransactionHandler::EntityTransactionHandler(HandlerTag tag,
EntityTransactionService::Stub *stub,
grpc::CompletionQueue *completion_queue,
MultiTransactionRequest *request,
MultiTransactionResponse *response)
: UnaryRpcHandler(completion_queue), tag_(tag), stub_(stub), request_(request),
response_(response) {}
void EntityTransactionHandler::handleNewCallState() {
CAOSDB_LOG_TRACE(logger_name)
<< "Enter EntityTransactionHandler::handleNewCallState with "
"CompletionQueue "
<< completion_queue;
CAOSDB_LOG_TRACE(logger_name) << "Enter EntityTransactionHandler::handleNewCallState with "
"CompletionQueue "
<< completion_queue;
rpc_ = stub_->PrepareAsyncMultiTransaction(&call_context, *request_,
completion_queue);
rpc_ = stub_->PrepareAsyncMultiTransaction(&call_context, *request_, completion_queue);
state_ = CallState::CallComplete;
rpc_->StartCall();
rpc_->Finish(response_, &status_, tag_);
CAOSDB_LOG_TRACE(logger_name)
<< "Leave EntityTransactionHandler::handleNewCallState";
CAOSDB_LOG_TRACE(logger_name) << "Leave EntityTransactionHandler::handleNewCallState";
}
} // namespace caosdb::transaction
......@@ -74,8 +74,7 @@ bool UnaryRpcHandler::OnNext(bool ok) {
return false;
}
} else {
CAOSDB_LOG_ERROR(logger_name)
<< "UnaryRpcHandler::OnNext(false)!. This should not happen.";
CAOSDB_LOG_ERROR(logger_name) << "UnaryRpcHandler::OnNext(false)!. This should not happen.";
// TODO(tf) Handle this error:
// in CallComplete state: "Client-side Finish: ok should always be true"
// in ReceivingFile state: "ok indicates that the RPC is going to go to
......@@ -88,15 +87,13 @@ bool UnaryRpcHandler::OnNext(bool ok) {
return true;
} catch (std::exception &e) {
CAOSDB_LOG_ERROR(logger_name)
<< "UnaryRpcHandler caught an exception: " << e.what();
CAOSDB_LOG_ERROR(logger_name) << "UnaryRpcHandler caught an exception: " << e.what();
transaction_status = TransactionStatus::GENERIC_ERROR(e.what());
state_ = CallState::CallComplete;
} catch (...) {
CAOSDB_LOG_ERROR(logger_name)
<< "Transaction error: unknown exception caught";
transaction_status = TransactionStatus::GENERIC_ERROR(
"UnaryRpcHandler caught an unknown exception");
CAOSDB_LOG_ERROR(logger_name) << "Transaction error: unknown exception caught";
transaction_status =
TransactionStatus::GENERIC_ERROR("UnaryRpcHandler caught an unknown exception");
state_ = CallState::CallComplete;
}
......@@ -110,8 +107,7 @@ bool UnaryRpcHandler::OnNext(bool ok) {
void UnaryRpcHandler::Cancel() { call_context.TryCancel(); }
void UnaryRpcHandler::handleCallCompleteState() {
CAOSDB_LOG_TRACE(logger_name)
<< "Enter UnaryRpcHandler::handleCallCompleteState";
CAOSDB_LOG_TRACE(logger_name) << "Enter UnaryRpcHandler::handleCallCompleteState";
switch (status_.error_code()) {
case grpc::OK:
......@@ -122,14 +118,12 @@ void UnaryRpcHandler::handleCallCompleteState() {
std::string description(get_status_description(code) +
" Original message: " + status_.error_message());
transaction_status = TransactionStatus(code, description);
CAOSDB_LOG_ERROR(logger_name)
<< "UnaryRpcHandler finished with an error (Code " << code
<< "): " << description;
CAOSDB_LOG_ERROR(logger_name) << "UnaryRpcHandler finished with an error (Code " << code
<< "): " << description;
break;
}
CAOSDB_LOG_TRACE(logger_name)
<< "Leave UnaryRpcHandler::handleCallCompleteState";
CAOSDB_LOG_TRACE(logger_name) << "Leave UnaryRpcHandler::handleCallCompleteState";
}
} // namespace caosdb::transaction
/*
* This file is a part of the CaosDB Project.
*
* Copyright (C) 2021 Daniel Hornung <d.hornung@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/data_type.h"
#include "caosdb/entity.h"
#include "caosdb/utility.h"
#include <algorithm>
namespace caosdb::utility {
using caosdb::entity::AtomicDataType;
using caosdb::entity::Importance;
using caosdb::entity::Role;
// using emap = std::map<int, std::string>; // enum mapping
// Enum helper template specializations //////////////////////////////////////
template <> auto getEnumNameFromValue<Importance>(Importance v) -> std::string {
auto result = caosdb::entity::importance_names.at(v);
return result;
}
template <> auto getEnumNameFromValue<Role>(Role v) -> std::string {
auto result = caosdb::entity::role_names.at(v);
return result;
}
template <> auto getEnumNameFromValue<AtomicDataType>(AtomicDataType v) -> std::string {
auto result = caosdb::entity::atomicdatatype_names.at(v);
return result;
}
template <> auto getEnumValueFromName<Importance>(const std::string &name) -> Importance {
// TODO (dh): Why does this compile?
// if (caosdb::entity::importance_names.begin()->second == name) {}
// std::for_each(caosdb::entity::importance_names.begin(),
// caosdb::entity::importance_names.end(),
// [](const auto &entry){});
// TODO (dh): Whereas this does not?
// auto result = std::find(caosdb::entity::importance_names.cbegin(),
// caosdb::entity::importance_names.cend(),
// [name](const auto& entry){ return entry.second == name; });
// Workaround: plaint old iteration:
for (auto const &entry : caosdb::entity::importance_names) {
if (entry.second == name) {
return entry.first;
}
}
throw std::out_of_range(std::string("Could not find enum value for string '") + name + "'.");
}
template <> auto getEnumValueFromName<AtomicDataType>(const std::string &name) -> AtomicDataType {
for (auto const &entry : caosdb::entity::atomicdatatype_names) {
if (entry.second == name) {
return entry.first;
}
}
throw std::out_of_range(std::string("Could not find enum value for string '") + name + "'.");
}
template <> auto getEnumValueFromName<Role>(const std::string &name) -> Role {
for (auto const &entry : caosdb::entity::role_names) {
if (entry.second == name) {
return entry.first;
}
}
throw std::out_of_range(std::string("Could not find enum value for string '") + name + "'.");
}
// End of template specialization /////////////////////////////////////////////
} // namespace caosdb::utility
This diff is collapsed.
......@@ -4,30 +4,25 @@
int main(void) {
int status = 0; // last function return value
printf(
"CaosDB C client (libcaosdb %d.%d.%d)\nWe don't miss the H of caos.\n\n",
LIBCAOSDB_VERSION_MAJOR, LIBCAOSDB_VERSION_MINOR, LIBCAOSDB_VERSION_PATCH);
printf("CaosDB C client (libcaosdb %d.%d.%d)\nWe don't miss the H of caos.\n\n",
LIBCAOSDB_VERSION_MAJOR, LIBCAOSDB_VERSION_MINOR, LIBCAOSDB_VERSION_PATCH);
caosdb_connection_connection connection;
status =
caosdb_connection_connection_manager_get_default_connection(&connection);
status = caosdb_connection_connection_manager_get_default_connection(&connection);
if (status != 0) {
printf("An error occured: ERROR %d - %s\n", status,
caosdb_get_status_description(status));
printf("An error occured: ERROR %d - %s\n", status, caosdb_get_status_description(status));
return status;
}
caosdb_info_version_info version_info;
status = caosdb_connection_get_version_info(&version_info, &connection);
if (status != 0) {
printf("An error occured: ERROR %d - %s\n", status,
caosdb_get_status_description(status));
printf("An error occured: ERROR %d - %s\n", status, caosdb_get_status_description(status));
return status;
}
printf("Server version: %d.%d.%d-%s-%s\n", version_info.major,
version_info.minor, version_info.patch, version_info.pre_release,
version_info.build);
printf("Server version: %d.%d.%d-%s-%s\n", version_info.major, version_info.minor,
version_info.patch, version_info.pre_release, version_info.build);
return 0;
}
......@@ -33,23 +33,19 @@
auto main() -> int {
std::cout << "CaosDB C++ client (libcaosdb "
<< caosdb::LIBCAOSDB_VERSION_MINOR << "."
<< caosdb::LIBCAOSDB_VERSION_MINOR << "."
<< caosdb::LIBCAOSDB_VERSION_PATCH << ")\n"
std::cout << "CaosDB C++ client (libcaosdb " << caosdb::LIBCAOSDB_VERSION_MINOR << "."
<< caosdb::LIBCAOSDB_VERSION_MINOR << "." << caosdb::LIBCAOSDB_VERSION_PATCH << ")\n"
<< "We don't miss the H of caos.\n"
<< std::endl;
try {
const auto &connection =
caosdb::connection::ConnectionManager::GetDefaultConnection();
const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection();
connection->RetrieveVersionInfoNoExceptions();
// get version info of the server
const auto &v_info = connection->GetVersionInfo();
std::cout << "Server Version: " << v_info->GetMajor() << "."
<< v_info->GetMinor() << "." << v_info->GetPatch() << "-"
<< v_info->GetPreRelease() << "-" << v_info->GetBuild()
std::cout << "Server Version: " << v_info->GetMajor() << "." << v_info->GetMinor() << "."
<< v_info->GetPatch() << "-" << v_info->GetPreRelease() << "-" << v_info->GetBuild()
<< std::endl;
// retrieve an entity
......@@ -57,12 +53,10 @@ auto main() -> int {
transaction->RetrieveById("20");
transaction->Execute();
const auto &result_set =
dynamic_cast<const caosdb::transaction::UniqueResult &>(
transaction->GetResultSet());
dynamic_cast<const caosdb::transaction::UniqueResult &>(transaction->GetResultSet());
// print description
std::cout << "Entity Description: "
<< result_set.GetEntity().GetDescription() << std::endl;
std::cout << "Entity Description: " << result_set.GetEntity().GetDescription() << std::endl;
return 0;
} catch (const caosdb::exceptions::ConfigurationError &exc) {
......
......@@ -60,15 +60,16 @@ foreach (i RANGE "${len_test_cases}")
target_include_directories(${test_case_name}
PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
if(_LINTING)
set_target_properties(${test_case_name}
PROPERTIES
CXX_CLANG_TIDY "${_CMAKE_CXX_CLANG_TIDY};${_CMAKE_CXX_CLANG_TIDY_TEST_CHECKS}"
CXX_INCLUDE_WHAT_YOU_USE "${_CMAKE_CXX_INCLUDE_WHAT_YOU_USE}")
set_target_properties(${test_case_name}
PROPERTIES
CXX_CLANG_TIDY "${_CMAKE_CXX_CLANG_TIDY};${_CMAKE_CXX_CLANG_TIDY_TEST_CHECKS}"
CXX_INCLUDE_WHAT_YOU_USE "${_CMAKE_CXX_INCLUDE_WHAT_YOU_USE}")
endif()
gtest_discover_tests(${test_case_name}
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
PROPERTIES
LABELS "caosdb-cpplib-unit-tests")
LABELS "caosdb-cpplib-unit-tests"
)
endforeach ()
# copy test data to build dir
......
......@@ -29,31 +29,47 @@
* @author Timm Fitschen
* @date 2021-07-07
*/
#define EXPECT_THROW_MESSAGE(statement, exeption_type, message) \
EXPECT_THROW( \
try { statement; } catch (const exeption_type &e) { \
EXPECT_EQ(std::string(e.what()), message); \
throw; \
}, \
exeption_type)
#define ASSERT_THROW_MESSAGE(statement, exeption_type, message) \
ASSERT_THROW( \
try { statement; } catch (const exeption_type &e) { \
ASSERT_EQ(std::string(e.what()), message); \
throw; \
}, \
exeption_type)
#define EXPECT_NULL(statement) \
if (statement != nullptr) { \
FAIL() << "Should be a nullptr"; \
} else { \
SUCCEED(); \
#define EXPECT_THROW_MESSAGE(statement, exception_type, message) \
EXPECT_THROW( \
try { statement; } catch (const exception_type &e) { \
EXPECT_EQ(std::string(e.what()), message); \
throw; \
}, \
exception_type)
#define ASSERT_THROW_MESSAGE(statement, exception_type, message) \
ASSERT_THROW( \
try { statement; } catch (const exception_type &e) { \
ASSERT_EQ(std::string(e.what()), message); \
throw; \
}, \
exception_type)
#define EXPECT_THROW_STARTS_WITH(statement, exception_type, pattern) \
EXPECT_THROW( \
try { statement; } catch (const exception_type &e) { \
auto pat_s = std::string(pattern); \
EXPECT_EQ(std::string(e.what()).substr(0, pat_s.size()), pat_s); \
throw; \
}, \
exception_type)
#define ASSERT_THROW_STARTS_WITH(statement, exception_type, message) \
ASSERT_THROW( \
try { statement; } catch (const exception_type &e) { \
auto pat_s = std::string(pattern); \
ASSERT_EQ(std::string(e.what()).substr(0, pat_s.size()), pat_s); \
throw; \
}, \
exception_type)
#define EXPECT_NULL(statement) \
if (statement != nullptr) { \
FAIL() << "Should be a nullptr"; \
} else { \
SUCCEED(); \
}
#define ASSERT_NULL(statement) \
if (statement != nullptr) { \
ADD_FAIL() << "Should be a nullptr"; \
} else { \
SUCCEED(); \
#define ASSERT_NULL(statement) \
if (statement != nullptr) { \
ADD_FAIL() << "Should be a nullptr"; \
} else { \
SUCCEED(); \
}
#endif
......
......@@ -39,20 +39,16 @@ protected:
TEST_DATA_DIR + "/test_caosdb_client.json");
}
void TearDown() override {
caosdb::configuration::ConfigurationManager::Clear();
}
void TearDown() override { caosdb::configuration::ConfigurationManager::Clear(); }
};
TEST_F(test_ccaosdb, test_get_env_var) {
const char *const some_var =
caosdb_utility_get_env_var("SOME_ENV_VAR", "fall-back");
const char *const some_var = caosdb_utility_get_env_var("SOME_ENV_VAR", "fall-back");
EXPECT_EQ("fall-back", some_var);
}
TEST_F(test_ccaosdb, test_other_client_error) {
EXPECT_EQ(caosdb_status_code_OTHER_CLIENT_ERROR(),
caosdb::StatusCode::OTHER_CLIENT_ERROR);
EXPECT_EQ(caosdb_status_code_OTHER_CLIENT_ERROR(), caosdb::StatusCode::OTHER_CLIENT_ERROR);
}
TEST_F(test_ccaosdb, test_get_default_connection) {
......@@ -65,23 +61,20 @@ TEST_F(test_ccaosdb, test_get_default_connection) {
TEST_F(test_ccaosdb, test_get_connection) {
caosdb_connection_connection out;
caosdb_connection_connection_manager_get_connection(&out,
"local-caosdb-admin");
caosdb_connection_connection_manager_get_connection(&out, "local-caosdb-admin");
EXPECT_TRUE(out.wrapped_connection);
}
TEST_F(test_ccaosdb, test_execute_transaction) {
caosdb_connection_connection connection;
caosdb_connection_connection_manager_get_connection(&connection,
"local-caosdb-admin");
caosdb_connection_connection_manager_get_connection(&connection, "local-caosdb-admin");
caosdb_transaction_transaction transaction;
caosdb_connection_connection_create_transaction(&connection, &transaction);
EXPECT_TRUE(transaction.wrapped_transaction);
int return_code(
caosdb_transaction_transaction_retrieve_by_id(&transaction, "some_id"));
int return_code(caosdb_transaction_transaction_retrieve_by_id(&transaction, "some_id"));
EXPECT_EQ(return_code, caosdb::StatusCode::GO_ON);
return_code = caosdb_transaction_transaction_execute(&transaction);
......@@ -91,14 +84,12 @@ TEST_F(test_ccaosdb, test_execute_transaction) {
EXPECT_EQ(return_code, 0);
caosdb_transaction_transaction multi_transaction;
caosdb_connection_connection_create_transaction(&connection,
&multi_transaction);
caosdb_connection_connection_create_transaction(&connection, &multi_transaction);
// We explicitely want to define a C-style array here, so we disable
// linting
const char *ids[] = {"id1", "id2", "id3"}; // NOLINT
return_code =
caosdb_transaction_transaction_retrieve_by_ids(&multi_transaction, ids, 3);
return_code = caosdb_transaction_transaction_retrieve_by_ids(&multi_transaction, ids, 3);
EXPECT_EQ(return_code, caosdb::StatusCode::GO_ON);
return_code = caosdb_transaction_delete_transaction(&multi_transaction);
......@@ -108,20 +99,17 @@ TEST_F(test_ccaosdb, test_execute_transaction) {
TEST_F(test_ccaosdb, test_multi_retrieve) {
std::cout << "Entering test_multi_retrieve ..." << std::endl;
caosdb_connection_connection connection;
caosdb_connection_connection_manager_get_connection(&connection,
"local-caosdb-admin");
caosdb_connection_connection_manager_get_connection(&connection, "local-caosdb-admin");
std::cout << "Creating transaction" << std::endl;
caosdb_transaction_transaction multi_transaction;
caosdb_connection_connection_create_transaction(&connection,
&multi_transaction);
caosdb_connection_connection_create_transaction(&connection, &multi_transaction);
// We explicitely want to define a C-style array here, so we disable
// linting
const char *ids[] = {"id1", "id2", "id3"}; // NOLINT
std::cout << "Adding mutli retrieval ..." << std::endl;
int return_code(
caosdb_transaction_transaction_retrieve_by_ids(&multi_transaction, ids, 3));
int return_code(caosdb_transaction_transaction_retrieve_by_ids(&multi_transaction, ids, 3));
EXPECT_EQ(return_code, caosdb::StatusCode::GO_ON);
std::cout << "Deleting transaction ..." << std::endl;
......@@ -131,14 +119,12 @@ TEST_F(test_ccaosdb, test_multi_retrieve) {
TEST_F(test_ccaosdb, test_query) {
caosdb_connection_connection connection;
caosdb_connection_connection_manager_get_connection(&connection,
"local-caosdb-admin");
caosdb_connection_connection_manager_get_connection(&connection, "local-caosdb-admin");
caosdb_transaction_transaction transaction;
caosdb_connection_connection_create_transaction(&connection, &transaction);
int return_code(caosdb_transaction_transaction_query(
&transaction, "FIND ENTITY WITH id=123"));
int return_code(caosdb_transaction_transaction_query(&transaction, "FIND ENTITY WITH id=123"));
EXPECT_EQ(return_code, caosdb::StatusCode::GO_ON);
return_code = caosdb_transaction_delete_transaction(&transaction);
......
......@@ -39,52 +39,43 @@ protected:
};
TEST_F(test_configuration, load_json) {
ConfigurationManager::LoadSingleJSONConfiguration(TEST_DATA_DIR +
"/test_caosdb_client.json");
EXPECT_THROW_MESSAGE(
ConfigurationManager::LoadSingleJSONConfiguration("anything"),
ConfigurationError, "This CaosDB client has already been configured.");
ConfigurationManager::LoadSingleJSONConfiguration(TEST_DATA_DIR + "/test_caosdb_client.json");
EXPECT_THROW_MESSAGE(ConfigurationManager::LoadSingleJSONConfiguration("anything"),
ConfigurationError, "This CaosDB client has already been configured.");
ConfigurationManager::Clear();
EXPECT_THROW_MESSAGE(
ConfigurationManager::LoadSingleJSONConfiguration("anything"),
ConfigurationError, "Configuration file does not exist.");
EXPECT_THROW_MESSAGE(ConfigurationManager::LoadSingleJSONConfiguration("anything"),
ConfigurationError, "Configuration file does not exist.");
ConfigurationManager::Clear();
}
TEST_F(test_configuration, get_default_connection_configuration_error) {
EXPECT_THROW_MESSAGE(ConfigurationManager::GetDefaultConnectionName(),
ConfigurationError,
EXPECT_THROW_MESSAGE(ConfigurationManager::GetDefaultConnectionName(), ConfigurationError,
"This CaosDB client has not been configured.");
ConfigurationManager::LoadSingleJSONConfiguration(
TEST_DATA_DIR + "/test_broken_caosdb_client_no_connections1.json");
EXPECT_THROW_MESSAGE(ConfigurationManager::GetDefaultConnectionName(),
ConfigurationError,
EXPECT_THROW_MESSAGE(ConfigurationManager::GetDefaultConnectionName(), ConfigurationError,
"This CaosDB client hasn't any configured connections.");
ConfigurationManager::Clear();
ConfigurationManager::LoadSingleJSONConfiguration(
TEST_DATA_DIR + "/test_broken_caosdb_client_no_connections2.json");
EXPECT_THROW_MESSAGE(ConfigurationManager::GetDefaultConnectionName(),
ConfigurationError,
EXPECT_THROW_MESSAGE(ConfigurationManager::GetDefaultConnectionName(), ConfigurationError,
"This CaosDB client hasn't any configured connections.");
ConfigurationManager::Clear();
ConfigurationManager::LoadSingleJSONConfiguration(
TEST_DATA_DIR + "/test_broken_caosdb_client_no_connections3.json");
EXPECT_THROW_MESSAGE(ConfigurationManager::GetDefaultConnectionName(),
ConfigurationError,
EXPECT_THROW_MESSAGE(ConfigurationManager::GetDefaultConnectionName(), ConfigurationError,
"This CaosDB client hasn't any configured connections.");
ConfigurationManager::Clear();
}
TEST_F(test_configuration, initialize_logging) {
auto logging_configuration =
caosdb::logging::LoggingConfiguration(CAOSDB_LOG_LEVEL_ALL);
auto console_sink =
std::make_shared<caosdb::logging::ConsoleSinkConfiguration>(
"console", CAOSDB_DEFAULT_LOG_LEVEL);
auto logging_configuration = caosdb::logging::LoggingConfiguration(CAOSDB_LOG_LEVEL_ALL);
auto console_sink = std::make_shared<caosdb::logging::ConsoleSinkConfiguration>(
"console", CAOSDB_DEFAULT_LOG_LEVEL);
logging_configuration.AddSink(console_sink);
initialize_logging(logging_configuration);
......
......@@ -40,8 +40,7 @@ class test_connection : public ::testing::Test {
protected:
void SetUp() override {
ConfigurationManager::Clear();
ConfigurationManager::LoadSingleJSONConfiguration(
TEST_DATA_DIR + "/test_caosdb_client.json");
ConfigurationManager::LoadSingleJSONConfiguration(TEST_DATA_DIR + "/test_caosdb_client.json");
};
void TearDown() override { ConfigurationManager::Clear(); };
};
......
......@@ -20,21 +20,19 @@
*
*/
#include "caosdb/data_type.h" // for DataType, AtomicDataType
#include "caosdb/entity.h" // for Entity
#include "caosdb/entity/v1alpha1/main.pb.h" // for AtomicDataType, DataType
#include "caosdb/logging.h" // for CAOSDB_LOG_DEBUG
#include "caosdb/protobuf_helper.h" // for CAOSDB_DEBUG_...
#include <boost/log/core/record.hpp> // for record
#include "caosdb/data_type.h" // for DataType, AtomicDataType
#include "caosdb/entity.h" // for Entity
#include "caosdb/logging.h" // for CAOSDB_LOG_DEBUG
#include <boost/log/core/record.hpp> // for record
#include <boost/log/detail/attachable_sstream_buf.hpp> // for basic_ostring...
#include <boost/log/sources/record_ostream.hpp> // for operator<<
#include <boost/preprocessor/seq/limits/enum_256.hpp> // for BOOST_PP_SEQ_...
#include <boost/preprocessor/seq/limits/size_256.hpp> // for BOOST_PP_SEQ_...
#include <gtest/gtest-message.h> // for Message
#include <gtest/gtest-test-part.h> // for TestPartResult, SuiteApi...
#include <gtest/gtest_pred_impl.h> // for AssertionResult, Test
#include <iosfwd> // for streamsize
#include <string> // for allocator
#include <gtest/gtest-test-part.h> // for TestPartResult, SuiteApi...
#include <gtest/gtest_pred_impl.h> // for AssertionResult, Test
#include <iosfwd> // for streamsize
#include <string> // for allocator
namespace caosdb::entity {
using ProtoEntity = caosdb::entity::v1alpha1::Entity;
......@@ -45,15 +43,15 @@ using ProtoAtomicDataType = caosdb::entity::v1alpha1::AtomicDataType;
TEST(test_data_type, test_atomic) {
ProtoDataType proto_data_type;
for (int i = 1; i < 6; i++) {
for (const auto &map_el : atomicdatatype_names) {
Entity entity;
entity.SetRole(Role::PROPERTY);
// the different AtomicDataType are associated with integers
entity.SetDataType(static_cast<AtomicDataType>(i));
entity.SetDataType(map_el.first);
EXPECT_TRUE(entity.GetDataType().IsAtomic());
EXPECT_EQ(entity.GetDataType().AsAtomic(), static_cast<AtomicDataType>(i));
EXPECT_EQ(entity.GetDataType().AsAtomic(), map_el.first);
proto_data_type.set_atomic_data_type(static_cast<ProtoAtomicDataType>(i));
proto_data_type.set_atomic_data_type(static_cast<ProtoAtomicDataType>(map_el.first));
DataType data_type(&proto_data_type);
entity.SetDataType(data_type);
......@@ -61,7 +59,7 @@ TEST(test_data_type, test_atomic) {
EXPECT_EQ(data_type.AsReference().GetName(), std::basic_string<char>(""));
EXPECT_FALSE(data_type.IsList());
EXPECT_TRUE(data_type.IsAtomic());
EXPECT_EQ(data_type.AsAtomic(), static_cast<AtomicDataType>(i));
EXPECT_EQ(data_type.AsAtomic(), map_el.first);
}
}
......@@ -85,33 +83,22 @@ TEST(test_data_type, test_reference) {
}
TEST(test_data_type, test_list_of_atomic) {
ProtoDataType proto_data_type;
auto *proto_list_data_type = proto_data_type.mutable_list_data_type();
for (int i = 1; i < 6; i++) {
proto_list_data_type->set_atomic_data_type(
static_cast<ProtoAtomicDataType>(i));
DataType data_type(&proto_data_type);
for (const auto &map_el : atomicdatatype_names) {
DataType data_type(map_el.first, true);
EXPECT_FALSE(data_type.IsReference());
EXPECT_FALSE(data_type.IsAtomic());
EXPECT_TRUE(data_type.IsList());
const auto &list_data_type = data_type.AsList();
EXPECT_EQ(list_data_type.GetReferenceDataType().GetName(),
std::basic_string<char>(""));
EXPECT_EQ(list_data_type.GetReferenceDataType().GetName(), std::basic_string<char>(""));
EXPECT_TRUE(list_data_type.IsListOfAtomic());
EXPECT_FALSE(list_data_type.IsListOfReference());
EXPECT_EQ(list_data_type.GetAtomicDataType(),
static_cast<AtomicDataType>(i));
EXPECT_EQ(list_data_type.GetAtomicDataType(), map_el.first);
}
}
TEST(test_data_type, test_list_of_reference) {
ProtoDataType proto_data_type;
auto *proto_list_data_type = proto_data_type.mutable_list_data_type();
proto_list_data_type->mutable_reference_data_type()->set_name("person");
DataType data_type(&proto_data_type);
auto data_type = DataType("person", true);
EXPECT_FALSE(data_type.IsReference());
EXPECT_FALSE(data_type.IsAtomic());
......
......@@ -85,6 +85,29 @@ TEST(test_entity, test_property_setters) {
EXPECT_EQ(prop.GetUnit(), "prop_unit");
EXPECT_TRUE(prop.GetDataType().IsReference());
EXPECT_EQ(prop.GetDataType().AsReference().GetName(), "prop_dtype");
EXPECT_FALSE(prop.GetDataType().IsList());
prop.SetDataType(AtomicDataType::DATETIME);
EXPECT_TRUE(prop.GetDataType().IsAtomic());
EXPECT_EQ(prop.GetDataType().AsAtomic(), AtomicDataType::DATETIME);
EXPECT_FALSE(prop.GetDataType().IsList());
}
TEST(test_entity, test_list_property_setters) {
auto prop = Property();
prop.SetDataType(AtomicDataType::DATETIME); // Set as atomic first.
EXPECT_TRUE(prop.GetDataType().IsAtomic());
EXPECT_EQ(prop.GetDataType().AsAtomic(), AtomicDataType::DATETIME);
prop.SetDataType(AtomicDataType::DOUBLE, true);
auto const &dtype = prop.GetDataType();
EXPECT_FALSE(dtype.IsAtomic()); // Should not be true anymore.
EXPECT_FALSE(dtype.IsReference());
EXPECT_TRUE(dtype.IsList());
EXPECT_NE(dtype.AsAtomic(), AtomicDataType::DATETIME); // Should be overwritten.
EXPECT_TRUE(dtype.AsList().IsListOfAtomic());
EXPECT_EQ(dtype.AsList().GetAtomicDataType(), AtomicDataType::DOUBLE);
}
TEST(test_entity, test_append_property) {
......@@ -132,8 +155,7 @@ TEST(test_entity, test_copy_to) {
// create protobuf entity to which all fields ae copied and then a
// CaoosDB entity from that protobuf entity.
auto *proto_copy =
google::protobuf::Arena::CreateMessage<ProtoEntity>(get_arena());
auto *proto_copy = google::protobuf::Arena::CreateMessage<ProtoEntity>(get_arena());
entity.CopyTo(proto_copy);
auto copied = Entity(proto_copy);
......@@ -257,8 +279,7 @@ TEST(test_entity, test_from_id_response) {
EXPECT_TRUE(entity.HasErrors());
EXPECT_EQ(entity.GetErrors().size(), 1);
EXPECT_EQ(entity.GetErrors().at(0).GetDescription(), "error_desc");
EXPECT_EQ(entity.GetErrors().at(0).GetCode(),
MessageCode::ENTITY_DOES_NOT_EXIST);
EXPECT_EQ(entity.GetErrors().at(0).GetCode(), MessageCode::ENTITY_DOES_NOT_EXIST);
IdResponse idr_warnings_and_infos;
idr_warnings_and_infos.set_id("other_entity_id");
......@@ -275,8 +296,7 @@ TEST(test_entity, test_from_id_response) {
EXPECT_EQ(other_ent.GetWarnings().size(), 1);
EXPECT_TRUE(other_ent.HasWarnings());
EXPECT_EQ(other_ent.GetWarnings().at(0).GetDescription(), "warning_desc");
EXPECT_EQ(other_ent.GetWarnings().at(0).GetCode(),
MessageCode::ENTITY_HAS_NO_PROPERTIES);
EXPECT_EQ(other_ent.GetWarnings().at(0).GetCode(), MessageCode::ENTITY_HAS_NO_PROPERTIES);
EXPECT_EQ(other_ent.GetInfos().size(), 1);
EXPECT_EQ(other_ent.GetInfos().at(0).GetDescription(), "info_desc");
EXPECT_EQ(other_ent.GetInfos().at(0).GetCode(), MessageCode::UNSPECIFIED);
......@@ -290,8 +310,7 @@ TEST(test_entity, test_add_file_to_non_file_entity) {
TEST(test_entity, test_add_non_existing_file) {
Entity entity;
entity.SetRole(Role::FILE);
EXPECT_EQ(entity.SetLocalPath("non-existing/path"),
StatusCode::FILE_DOES_NOT_EXIST_LOCALLY);
EXPECT_EQ(entity.SetLocalPath("non-existing/path"), StatusCode::FILE_DOES_NOT_EXIST_LOCALLY);
}
TEST(test_entity, test_add_directory_path) {
......@@ -439,8 +458,7 @@ TEST(test_entity, test_role) {
TEST(test_entity, test_add_file) {
Entity entity;
entity.SetRole(Role::FILE);
EXPECT_EQ(entity.SetLocalPath(TEST_DATA_DIR + "/test.json"),
StatusCode::SUCCESS);
EXPECT_EQ(entity.SetLocalPath(TEST_DATA_DIR + "/test.json"), StatusCode::SUCCESS);
}
} // namespace caosdb::entity
......@@ -23,9 +23,9 @@
#include <boost/filesystem/path.hpp> // for path
#include <boost/filesystem/path_traits.hpp> // for filesystem
#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 <string> // for string
#include <gtest/gtest-test-part.h> // for TestPartResult, SuiteApiResolver
#include <gtest/gtest_pred_impl.h> // for Test, EXPECT_EQ, AssertionResult
#include <string> // for string
namespace fs = boost::filesystem;
......@@ -35,9 +35,7 @@ class test_file_transmission : public ::testing::Test {
protected:
fs::path test_file_name;
void SetUp() override {
test_file_name = fs::path("this_is_a_test_file_remove_me.dat");
}
void SetUp() override { test_file_name = fs::path("this_is_a_test_file_remove_me.dat"); }
void TearDown() override { fs::remove(test_file_name); }
};
......
......@@ -94,14 +94,12 @@ TEST(test_protobuf, test_copy_nested) {
data_type_destination->mutable_reference_data_type()->set_name("dest_per");
EXPECT_EQ(entity_source.data_type().reference_data_type().name(), "src_per");
EXPECT_EQ(entity_destination.data_type().reference_data_type().name(),
"dest_per");
EXPECT_EQ(entity_destination.data_type().reference_data_type().name(), "dest_per");
entity_destination.CopyFrom(entity_source);
EXPECT_EQ(entity_source.data_type().reference_data_type().name(), "src_per");
EXPECT_EQ(entity_destination.data_type().reference_data_type().name(),
"src_per");
EXPECT_EQ(entity_destination.data_type().reference_data_type().name(), "src_per");
Entity entity(&entity_destination);
EXPECT_EQ(entity.GetDataType().AsReference().GetName(), "src_per");
......
......@@ -52,11 +52,10 @@ TEST(test_transaction, create_transaction) {
auto transaction = connection.CreateTransaction();
ASSERT_EQ(StatusCode::GO_ON, transaction->RetrieveById("100"));
EXPECT_THROW_MESSAGE(
transaction->Execute(), ConnectionError,
"The attempt to execute this transaction was not successful because the "
"connection to the server could not be established. "
"Original message: failed to connect to all addresses");
EXPECT_THROW_MESSAGE(transaction->Execute(), ConnectionError,
"The attempt to execute this transaction was not successful because the "
"connection to the server could not be established. "
"Original message: failed to connect to all addresses");
}
TEST(test_transaction, test_multi_result_set) {
......@@ -116,8 +115,7 @@ TEST(test_transaction, test_multi_result_iterator) {
std::vector<std::unique_ptr<Entity>> one_elem;
RetrieveResponse response;
response.mutable_entity_response()->mutable_entity()->set_id("100");
one_elem.push_back(
std::make_unique<Entity>(response.release_entity_response()));
one_elem.push_back(std::make_unique<Entity>(response.release_entity_response()));
MultiResultSet rs(std::move(one_elem));
EXPECT_EQ(rs.size(), 1);
......@@ -131,8 +129,7 @@ TEST(test_transaction, test_multi_result_set_one) {
std::vector<std::unique_ptr<Entity>> one_elem;
RetrieveResponse response;
response.mutable_entity_response()->mutable_entity()->set_id("100");
one_elem.push_back(
std::make_unique<Entity>(response.release_entity_response()));
one_elem.push_back(std::make_unique<Entity>(response.release_entity_response()));
MultiResultSet rs(std::move(one_elem));
EXPECT_EQ(rs.size(), 1);
......@@ -148,9 +145,8 @@ TEST(test_transaction, test_multi_result_set_three) {
->mutable_entity_response()
->mutable_entity()
->set_id("100");
auto *entity_with_error = response.add_responses()
->mutable_retrieve_response()
->mutable_entity_response();
auto *entity_with_error =
response.add_responses()->mutable_retrieve_response()->mutable_entity_response();
entity_with_error->mutable_entity()->set_id("101");
entity_with_error->add_errors()->set_code(1);
response.add_responses()
......
......@@ -24,6 +24,8 @@
#include "boost/beast/core/detail/base64.hpp" // for encoded_size
#include "boost/json/object.hpp" // for object
#include "boost/json/value.hpp" // for value
#include "caosdb/data_type.h" // for atomicdatatype_names
#include "caosdb/entity.h" // for importance_names, role...
#include "caosdb/utility.h" // for base64_encode, load_js...
#include "caosdb_test_utility.h" // for TEST_DATA_DIR
#include <gtest/gtest-message.h> // for Message
......@@ -53,4 +55,27 @@ TEST(test_utility, test_load_json_file) {
EXPECT_THAT(sub["see?"].as_array(), ElementsAre(true, false));
}
TEST(test_utility, enum_names) {
// All working enums
for (const auto &entry : caosdb::entity::importance_names) {
EXPECT_EQ(getEnumNameFromValue<caosdb::entity::Importance>(entry.first), entry.second);
EXPECT_EQ(getEnumValueFromName<caosdb::entity::Importance>(entry.second), entry.first);
}
for (const auto &entry : caosdb::entity::role_names) {
EXPECT_EQ(getEnumNameFromValue<caosdb::entity::Role>(entry.first), entry.second);
EXPECT_EQ(getEnumValueFromName<caosdb::entity::Role>(entry.second), entry.first);
}
for (const auto &entry : caosdb::entity::atomicdatatype_names) {
EXPECT_EQ(getEnumNameFromValue<caosdb::entity::AtomicDataType>(entry.first), entry.second);
EXPECT_EQ(getEnumValueFromName<caosdb::entity::AtomicDataType>(entry.second), entry.first);
}
// Some non-working examples
EXPECT_THROW_MESSAGE(getEnumValueFromName<caosdb::entity::Importance>("Invalid name"),
std::out_of_range, "Could not find enum value for string 'Invalid name'.");
enum e1 { a };
EXPECT_THROW_STARTS_WITH(getEnumNameFromValue<e1>(a), std::logic_error, "Enum type ");
EXPECT_THROW_STARTS_WITH(getEnumValueFromName<e1>("Hello!"), std::logic_error, "Enum type ");
}
} // namespace caosdb::utility