/* * This file is a part of the LinkAhead Project. * * Copyright (C) 2022 IndiScale GmbH <info@indiscale.com> * Copyright (C) 2022 Timm Fitschen <t.fitschen@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 "linkahead/entity.h" // for Entity, Property #include "linkahead/connection.h" // for Connection, Connec... #include "linkahead/message_code.h" // for ENTITY_DOES_NOT_EXIST, Messag... #include "linkahead/status_code.h" // for StatusCode, SUCCESS #include "linkahead/transaction.h" // for Entity, Transaction #include "linkahead/transaction_status.h" // for TransactionStatus #include <chrono> // for operator""ms, chrono_literals #include <gtest/gtest-message.h> // for Message #include <gtest/gtest-test-part.h> // for TestPartResult #include <gtest/gtest_pred_impl.h> // for AssertionResult #include <memory> // for allocator, unique_ptr, __shar... #include <thread> namespace linkahead::transaction { using linkahead::entity::MessageCode; /* * Test the retrieval of a non-existing entity * * The transaction is being executed and we can retrieve the state in the mean * time. */ TEST(test_async, retrieve_non_existing) { using namespace std::chrono_literals; const auto &connection = linkahead::connection::ConnectionManager::GetDefaultConnection(); auto transaction(connection->CreateTransaction()); const auto *id = "non-existing-id"; transaction->RetrieveById(id); transaction->ExecuteAsynchronously(); auto status = transaction->GetStatus(); EXPECT_EQ(status.GetCode(), StatusCode::EXECUTING); // 1000ms are not always sufficient, when there is very high pipeline load. auto count = 1000; auto code = transaction->GetStatus().GetCode(); do { // wait some time std::this_thread::sleep_for(10ms); // DONT call WaitForIt -> the transaction finishes in the background code = transaction->GetStatus().GetCode(); } while (--count > 0 && code == StatusCode::EXECUTING); ASSERT_GT(count, 0) << "ERROR: Timeout while waiting for transaction."; EXPECT_EQ(code, TransactionStatus::TRANSACTION_ERROR().GetCode()); ASSERT_EQ(code, StatusCode::GENERIC_TRANSACTION_ERROR); const auto &result_set = transaction->GetResultSet(); const auto &entity = result_set.at(0); EXPECT_EQ(id, entity.GetId()); EXPECT_TRUE(entity.HasErrors()); ASSERT_EQ(entity.GetErrors().size(), 1); EXPECT_EQ(entity.GetErrors().at(0).GetCode(), MessageCode::ENTITY_DOES_NOT_EXIST); } } // namespace linkahead::transaction