Skip to content
This repository has been archived by the owner on Apr 17, 2019. It is now read-only.

Commit

Permalink
StorageLimitTest
Browse files Browse the repository at this point in the history
Signed-off-by: Mikhail Boldyrev <[email protected]>
  • Loading branch information
MBoldyrev committed Apr 12, 2019
1 parent 7663aa5 commit a3e6f62
Show file tree
Hide file tree
Showing 2 changed files with 190 additions and 0 deletions.
8 changes: 8 additions & 0 deletions test/module/irohad/multi_sig_transactions/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,11 @@ target_link_libraries(mst_to_pcs_propagation_test
shared_model_proto_backend
test_logger
)

AddTest(storage_limit_test storage_limit_test.cpp)
target_link_libraries(storage_limit_test
schema
shared_model_interfaces_factories
shared_model_proto_backend
test_logger
)
182 changes: 182 additions & 0 deletions test/module/irohad/multi_sig_transactions/storage_limit_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
/**
* Copyright Soramitsu Co., Ltd. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

#include "multi_sig_transactions/storage/storage_limit.hpp"

#include <gtest/gtest.h>
#include "module/irohad/multi_sig_transactions/mst_test_helpers.hpp"
#include "module/shared_model/interface_mocks.hpp"

using namespace iroha;
using namespace testing;

class StorageLimitTest : public ::testing::Test {
protected:
std::shared_ptr<shared_model::interface::Transaction> makeTx() {
return clone(txBuilder(tx_counter_++).build());
}

std::shared_ptr<shared_model::interface::TransactionBatch> makeBatch(
size_t num_txs) {
shared_model::interface::types::SharedTxsCollectionType txs;
std::generate_n(
std::back_inserter(txs), num_txs, [this]() { return this->makeTx(); });
return createMockBatchWithTransactions(txs, {});
}

private:
size_t tx_counter_{0};
};

struct StorageImpl : public LimitableStorage {
bool insert(BatchPtr batch) override {
batches.emplace_back(std::move(batch));
return true;
}

std::vector<BatchPtr> batches;
};

template <typename Limit>
std::vector<std::shared_ptr<LimitedStorage<StorageImpl>>> generateStorages(
std::shared_ptr<Limit> limit, size_t num_storages) {
std::vector<std::shared_ptr<LimitedStorage<StorageImpl>>> storages;
storages.reserve(num_storages);
for (size_t i = 0; i < num_storages; ++i) {
storages.emplace_back(std::make_shared<LimitedStorage<StorageImpl>>(
limit, std::make_unique<StorageImpl>()));
}
return storages;
}

/**
* @given 5 storages with shared limit of 10 transactions
* @when first a batch with 2 transactionsa batch with 2 transactions is
* inserted to each storage, than a batch with single transactions is tried to
* be inserted to each storage
* @then first series of batches is inserted successfully and second is not
*/
TEST_F(StorageLimitTest, SharedLimitByTxs) {
auto storages = generateStorages(std::make_shared<StorageLimitByTxs>(10), 5);

for (auto &storage : storages) {
EXPECT_EQ(storage->batchesQuantity(), 0);
EXPECT_EQ(storage->transactionsQuantity(), 0);
EXPECT_TRUE(storage->insert(makeBatch(2)));
EXPECT_EQ(storage->batchesQuantity(), 1);
EXPECT_EQ(storage->transactionsQuantity(), 2);
}

for (auto &storage : storages) {
EXPECT_FALSE(storage->insert(makeBatch(1)));
EXPECT_EQ(storage->batchesQuantity(), 1);
EXPECT_EQ(storage->transactionsQuantity(), 2);
}
}

/**
* @given a storage with shared limit of 10 transactions
* @when another storage is created using its limit and is filled with 10
* transactions, then transactions are tried to be inserted to the first storage
* @then batches are not inserted to the first storage because it would violate
* the shared limit
*/
TEST_F(StorageLimitTest, SharedLimitAddStorage) {
LimitedStorage<StorageImpl> storage1{std::make_shared<StorageLimitByTxs>(10),
std::make_unique<StorageImpl>()};
LimitedStorage<StorageImpl> storage2{storage1.sharedLimit(),
std::make_unique<StorageImpl>()};
EXPECT_TRUE(storage2.insert(makeBatch(10)));
EXPECT_FALSE(storage1.insert(makeBatch(1)));
}

/**
* @given 2 storages with shared limit of 10 transactions filled to limit
* @when a batch with 3 transactions is removed from the first one
* @then the second can accept batches with up to 3 transactions in total
*/
TEST_F(StorageLimitTest, SharedLimitRemoveAndAdd) {
auto storages = generateStorages(std::make_shared<StorageLimitByTxs>(10), 2);
EXPECT_TRUE(storages[0]->insert(makeBatch(3)));
EXPECT_TRUE(storages[0]->insert(makeBatch(3)));
EXPECT_TRUE(storages[1]->insert(makeBatch(4)));

storages[0]->extract([](auto &storage) {
auto extracted_batch = std::move(*storage.batches.begin());
storage.batches.erase(storage.batches.begin());
return std::vector<BatchPtr>{extracted_batch};
});
EXPECT_EQ(storages[0]->batchesQuantity(), 1);
EXPECT_EQ(storages[0]->transactionsQuantity(), 3);

EXPECT_TRUE(storages[1]->insert(makeBatch(1)));
EXPECT_TRUE(storages[1]->insert(makeBatch(2)));
EXPECT_FALSE(storages[1]->insert(makeBatch(1)));
}

/**
* @given 2 storages with shared limit of 10 transactions filled to limit
* @when a batch with 3 transactions is moved from the first one
* @then both storages do not accept any new batches
* @and the second storage can accept the moved batch
*/
TEST_F(StorageLimitTest, SharedLimitMoveBatch) {
auto storages = generateStorages(std::make_shared<StorageLimitByTxs>(10), 2);
EXPECT_TRUE(storages[0]->insert(makeBatch(3)));
EXPECT_TRUE(storages[0]->insert(makeBatch(3)));
EXPECT_TRUE(storages[1]->insert(makeBatch(4)));

auto moved_batches = storages[0]->move([](auto &storage) {
std::vector<BatchPtr> extracted_batches;
extracted_batches.emplace_back(std::move(*storage.batches.begin()));
storage.batches.erase(storage.batches.begin());
return extracted_batches;
});
EXPECT_EQ(storages[0]->batchesQuantity(), 1);
EXPECT_EQ(storages[0]->transactionsQuantity(), 3);

EXPECT_FALSE(storages[0]->insert(makeBatch(1)));
EXPECT_FALSE(storages[1]->insert(makeBatch(1)));

ASSERT_EQ(moved_batches.size(), 1);
EXPECT_TRUE(storages[1]->insert(moved_batches.front()));
EXPECT_EQ(storages[1]->batchesQuantity(), 2);
EXPECT_EQ(storages[1]->transactionsQuantity(), 7);

EXPECT_FALSE(storages[0]->insert(makeBatch(1)));
EXPECT_FALSE(storages[1]->insert(makeBatch(1)));
}

/**
* @given 2 storages with shared limit of 10 transactions filled to limit
* @when a batch with 3 transactions is moved from the first one and then is
* destroyed without being inserted to any storage
* @then both storages can accept new batches with up to 3 transactions in total
*/
TEST_F(StorageLimitTest, SharedLimitMovedBatchDestroyed) {
auto storages = generateStorages(std::make_shared<StorageLimitByTxs>(10), 2);
EXPECT_TRUE(storages[0]->insert(makeBatch(3)));
EXPECT_TRUE(storages[0]->insert(makeBatch(3)));
EXPECT_TRUE(storages[1]->insert(makeBatch(4)));

{
auto moved_batches = storages[0]->move([](auto &storage) {
std::vector<BatchPtr> extracted_batches;
extracted_batches.emplace_back(std::move(*storage.batches.begin()));
storage.batches.erase(storage.batches.begin());
return extracted_batches;
});
EXPECT_EQ(moved_batches.size(), 1);

EXPECT_FALSE(storages[0]->insert(makeBatch(1)));
EXPECT_FALSE(storages[1]->insert(makeBatch(1)));
}

EXPECT_TRUE(storages[0]->insert(makeBatch(1)));
EXPECT_TRUE(storages[1]->insert(makeBatch(2)));

EXPECT_FALSE(storages[0]->insert(makeBatch(1)));
EXPECT_FALSE(storages[1]->insert(makeBatch(1)));
}

0 comments on commit a3e6f62

Please sign in to comment.