Skip to content

Commit

Permalink
Add AddAssetQuantity acceptance test (hyperledger-iroha#1120)
Browse files Browse the repository at this point in the history
Signed-off-by: Kitsu <[email protected]>
  • Loading branch information
l4l authored and x3medima17 committed Mar 30, 2018
1 parent b52a3e3 commit 111db9a
Show file tree
Hide file tree
Showing 2 changed files with 281 additions and 0 deletions.
8 changes: 8 additions & 0 deletions test/integration/acceptance/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ target_link_libraries(get_transactions_test
shared_model_stateless_validation
)

addtest(add_asset_qty_test add_asset_qty_test.cpp)
target_link_libraries(add_asset_qty_test
application
integration_framework
shared_model_proto_builders
shared_model_stateless_validation
)

addtest(create_role_test create_role_test.cpp)
target_link_libraries(create_role_test
application
Expand Down
273 changes: 273 additions & 0 deletions test/integration/acceptance/add_asset_qty_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,273 @@
/**
* Copyright Soramitsu Co., Ltd. 2018 All Rights Reserved.
* http://soramitsu.co.jp
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <gtest/gtest.h>
#include "backend/protobuf/transaction.hpp"
#include "cryptography/crypto_provider/crypto_defaults.hpp"
#include "datetime/time.hpp"
#include "framework/base_tx.hpp"
#include "framework/integration_framework/integration_test_framework.hpp"
#include "model/permissions.hpp"
#include "module/shared_model/builders/protobuf/test_transaction_builder.hpp"

using namespace std::string_literals;
using namespace integration_framework;
using namespace shared_model;

class AddAssetQuantity : public ::testing::Test {
public:
/**
* Creates the transaction with the user creation commands
* @param perms are the permissions of the user
* @return built tx and a hash of its payload
*/
auto makeUserWithPerms(const std::vector<std::string> &perms = {
iroha::model::can_add_asset_qty}) {
return framework::createUserWithPerms(
kUser, kUserKeypair.publicKey(), "role"s, perms)
.build()
.signAndAddSignature(kAdminKeypair);
}

/**
* Create valid base pre-built transaction
* @return pre-built tx
*/
auto baseTx() {
return TestUnsignedTransactionBuilder()
.txCounter(1)
.creatorAccountId(kUserId)
.createdTime(iroha::time::now());
}

/**
* Completes pre-built transaction
* @param builder is a pre-built tx
* @return built tx
*/
template <typename TestTransactionBuilder>
auto completeTx(TestTransactionBuilder builder) {
return builder.build().signAndAddSignature(kUserKeypair);
}

const std::string kUser = "user"s;
const std::string kAsset = IntegrationTestFramework::kAssetName + "#test";
const std::string kUserId = kUser + "@test";
const std::string kAmount = "1.0";
const crypto::Keypair kAdminKeypair =
crypto::DefaultCryptoAlgorithmType::generateKeypair();
const crypto::Keypair kUserKeypair =
crypto::DefaultCryptoAlgorithmType::generateKeypair();
};

/**
* @given some user with can_add_asset_qty permission
* @when execute tx with AddAssetQuantity command
* @then there is the tx in proposal
*/
TEST_F(AddAssetQuantity, Basic) {
IntegrationTestFramework()
.setInitialState(kAdminKeypair)
.sendTx(makeUserWithPerms())
.skipProposal()
.skipBlock()
.sendTx(completeTx(baseTx().addAssetQuantity(kUserId, kAsset, kAmount)))
.skipProposal()
.checkBlock(
[](auto &block) { ASSERT_EQ(block->transactions().size(), 1); })
.done();
}

/**
* @given some user without can_add_asset_qty permission
* @when execute tx with AddAssetQuantity command
* @then there is no tx in proposal
*/
TEST_F(AddAssetQuantity, NoPermissions) {
IntegrationTestFramework()
.setInitialState(kAdminKeypair)
.sendTx(makeUserWithPerms({iroha::model::can_get_my_txs}))
.skipProposal()
.skipBlock()
.sendTx(completeTx(baseTx().addAssetQuantity(kUserId, kAsset, kAmount)))
.skipProposal()
.checkBlock(
[](auto &block) { ASSERT_EQ(block->transactions().size(), 0); })
.done();
}

/**
* @given pair of users with all required permissions
* @when execute tx with AddAssetQuantity command with negative amount
* @then the tx hasn't passed stateless validation
* (aka skipProposal throws)
*/
TEST_F(AddAssetQuantity, NegativeAmount) {
IntegrationTestFramework itf;
itf.setInitialState(kAdminKeypair)
.sendTx(makeUserWithPerms())
.skipProposal()
.skipBlock()
.sendTx(completeTx(baseTx().addAssetQuantity(kUserId, kAsset, "-1.0")));
ASSERT_ANY_THROW(itf.skipProposal());
}

/**
* @given pair of users with all required permissions
* @when execute tx with AddAssetQuantity command with zero amount
* @then the tx hasn't passed stateless validation
* (aka skipProposal throws)
*/
TEST_F(AddAssetQuantity, ZeroAmount) {
IntegrationTestFramework itf;
itf.setInitialState(kAdminKeypair)
.sendTx(makeUserWithPerms())
.skipProposal()
.skipBlock()
.sendTx(completeTx(baseTx().addAssetQuantity(kUserId, kAsset, "0.0")));
ASSERT_ANY_THROW(itf.skipProposal());
}

/**
* @given pair of users with all required permissions
* @when execute two txes with AddAssetQuantity command with amount more than a
* uint256 max half
* @then first transaction is committed and there is an empty proposal for the
* second
*/
TEST_F(AddAssetQuantity, Uint256DestOverflow) {
const std::string &uint256_halfmax =
"723700557733226221397318656304299424082937404160253525246609900049457060"
"2495.0"; // 2**252 - 1
IntegrationTestFramework()
.setInitialState(kAdminKeypair)
.sendTx(makeUserWithPerms())
.skipProposal()
.skipBlock()
// Add first half of the maximum
.sendTx(completeTx(
baseTx().addAssetQuantity(kUserId, kAsset, uint256_halfmax)))
.skipProposal()
.checkBlock(
[](auto &block) { ASSERT_EQ(block->transactions().size(), 1); })
// Add second half of the maximum
.sendTx(completeTx(
baseTx().addAssetQuantity(kUserId, kAsset, uint256_halfmax)))
.skipProposal()
.checkBlock(
[](auto &block) { ASSERT_EQ(block->transactions().size(), 0); })
.done();
}

/**
* @given some user with all required permissions
* @when execute tx with AddAssetQuantity command with inexistent account
* @then there is an empty proposal
*/
TEST_F(AddAssetQuantity, InexistentAccount) {
const std::string &inexistent = "inexist@test"s;
IntegrationTestFramework()
.setInitialState(kAdminKeypair)
.sendTx(makeUserWithPerms())
.skipProposal()
.skipBlock()
.sendTx(
completeTx(baseTx().addAssetQuantity(inexistent, kAsset, kAmount)))
.skipProposal()
.checkBlock(
[](auto &block) { ASSERT_EQ(block->transactions().size(), 0); })
.done();
}

/**
* @given some user with all required permissions
* @when execute tx with AddAssetQuantity command with inexistent asset
* @then there is an empty proposal
*/
TEST_F(AddAssetQuantity, InexistentAsset) {
const std::string &inexistent = "inexist#test"s;
IntegrationTestFramework()
.setInitialState(kAdminKeypair)
.sendTx(makeUserWithPerms())
.skipProposal()
.skipBlock()
.sendTx(
completeTx(baseTx().addAssetQuantity(kUserId, inexistent, kAmount)))
.skipProposal()
.checkBlock(
[](auto &block) { ASSERT_EQ(block->transactions().size(), 0); })
.done();
}

/**
* @given some user with all required permission
* @when execute tx with AddAssetQuantity command to some other user
* @then there is no tx in proposal
*/
TEST_F(AddAssetQuantity, OtherUser) {
IntegrationTestFramework()
.setInitialState(kAdminKeypair)
.sendTx(makeUserWithPerms())
.skipProposal()
.skipBlock()
.sendTx(completeTx(baseTx().addAssetQuantity(
IntegrationTestFramework::kAdminId, kAsset, kAmount)))
.skipProposal()
.checkBlock(
[](auto &block) { ASSERT_EQ(block->transactions().size(), 0); })
.done();
}

/**
* @given pair of user in different domains with all required permission
* @when first one execute a tx with AddAssetQuantity command to the second one
* @then the tx hasn't passed stateless validation
* (aka skipProposal throws)
*/
TEST_F(AddAssetQuantity, OtherDomain) {
const auto kNewRole = "newrl";
const auto kNewDomain = "newdom";
const auto kNewUser = "newusr";
IntegrationTestFramework itf;
itf.setInitialState(kAdminKeypair)
.sendTx(makeUserWithPerms())
// Generate new domain, new user and an asset
.sendTx(
shared_model::proto::TransactionBuilder()
.txCounter(1)
.creatorAccountId(
integration_framework::IntegrationTestFramework::kAdminId)
.createdTime(iroha::time::now())
.createRole(
kNewRole,
std::vector<std::string>{iroha::model::can_get_my_txs})
.createDomain(kNewDomain, kNewRole)
.createAccount(
kNewUser,
kNewDomain,
crypto::DefaultCryptoAlgorithmType::generateKeypair()
.publicKey())
.createAsset(IntegrationTestFramework::kAssetName, kNewDomain, 1)
.build()
.signAndAddSignature(kAdminKeypair))
.skipProposal()
// Make sure everything is committed
.checkBlock(
[](auto &block) { ASSERT_EQ(block->transactions().size(), 2); })
.sendTx(completeTx(baseTx().addAssetQuantity(kNewUser, kAsset, kAmount)));
ASSERT_ANY_THROW(itf.skipProposal());
}

0 comments on commit 111db9a

Please sign in to comment.