-
Notifications
You must be signed in to change notification settings - Fork 295
Conversation
Signed-off-by: Kitsu <[email protected]>
.filter([&](auto s) { return s->transactionHash() == tx.hash(); }) | ||
.map([](auto s) { return TxStatus(s->get().which()); }) | ||
.filter([&statuses](auto s) { return statuses.count(s) != 0; }) | ||
.take_while([&statuses](auto) { return statuses.size() != 0; }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This chain calls probably can be improved, feel free to propose solution
Signed-off-by: Kitsu <[email protected]>
Signed-off-by: Kitsu <[email protected]>
/** | ||
* Send transactions to Iroha and validate obtained statuses | ||
* @param tx_sequence - transactions sequence | ||
* @param statuses - vector of statues list to be checked against, which |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo with statues
iroha_instance_->getIrohaInstance()->getCommandService()->ListTorii( | ||
tx_list); | ||
|
||
// wait, until all of the statuses are recieved |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: received
iroha_instance_->instance_->getStatusBus() | ||
->statuses() | ||
.filter([&](auto s) { return s->transactionHash() == tx.hash(); }) | ||
.map([](auto s) { return TxStatus(s->get().which()); }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dangerous cast from variant to enum. If someone changes the order of types in either variant or enum it will be hard to find the reason of the error. Maybe cast it explicitly via visit_in_place?
return tx_statsues.find(s->transactionHash()) != tx_statsues.end(); | ||
}) | ||
.subscribe([&](auto s) { | ||
auto status = TxStatus(s->get().which()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same. Maybe we can define a separate function, responsible for such conversion?
Signed-off-by: Kitsu <[email protected]>
Signed-off-by: Kitsu <[email protected]>
Signed-off-by: Kitsu <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This approach does not allow to compare the error message in responses, and introduces code duplication for statuses. Consider accepting a visitor for each transaction.
|
||
// mapping transaction hash to its statuses that need to be checked | ||
std::map<shared_model::crypto::Hash, std::set<TxStatus>, HashCmp> | ||
tx_statsues; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix that typo
This reverts commit 047cb29. Signed-off-by: Kitsu <[email protected]>
Signed-off-by: Kitsu <[email protected]>
fa2421a
to
aa000a8
Compare
if (response != statuses.end()) { | ||
statuses.erase(response); | ||
} | ||
status_list.emplace_back(iroha::protocol::ToriiResponse( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we make status list to be vector of interfaces and use clone function instead of copying protobuf explicitly?
const shared_model::proto::Transaction &tx, std::set<TxStatus> statuses) { | ||
const shared_model::proto::Transaction &tx, | ||
std::function< | ||
void(const std::vector<shared_model::proto::TransactionResponse> &)> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we change to interface::TransactionResponse?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
only if it std::vector<std::shared_ptr<iface::TxResponse>>
@@ -153,8 +153,12 @@ namespace integration_framework { | |||
* @param statuses - list of statuses to check against | |||
* @return this | |||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update comment
makeUserWithPerms(), | ||
[](auto &resps) { | ||
for (auto &&r : resps) { | ||
std::cout << r.get().which() << std::endl; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did yoy forget to remove that?
IntegrationTestFramework &sendTx(const shared_model::proto::Transaction &tx, | ||
std::set<TxStatus> statuses); | ||
IntegrationTestFramework &sendTx( | ||
const shared_model::proto::Transaction &tx, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, can we work with interfaces here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's consistent with ITF interface, so what's the point?
Signed-off-by: Kitsu <[email protected]>
SonarQube analysis reported 3 issues
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
status_count approach will not work because in case a new status is added, it may be required to refactor all the tests with the new value. It is required to discuss another possible approaches.
Signed-off-by: Kitsu <[email protected]>
537b522
to
6c3f151
Compare
Signed-off-by: Kitsu <[email protected]>
@@ -276,6 +289,18 @@ namespace integration_framework { | |||
tbb::concurrent_queue<ProposalType> proposal_queue_; | |||
tbb::concurrent_queue<ProposalType> verified_proposal_queue_; | |||
tbb::concurrent_queue<BlockType> block_queue_; | |||
|
|||
struct HashCmp { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this really required? Maybe use std::string from hash hex instead?
}; | ||
|
||
std::map<shared_model::interface::types::HashType, | ||
tbb::concurrent_queue<TxResponseType>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Observable does not emit values concurrently, so there is no need in a concurrent queue for pushes. Reads are also done in main test thread, so read concurrency is also not required.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
gRPC-based thread is writing here and the ITF main thread is reading. So there should be concurrent queue
template <typename T> | ||
void checkStatus(const shared_model::interface::TransactionResponse &resp) { | ||
ASSERT_NO_THROW( | ||
boost::apply_visitor(framework::SpecifiedVisitor<T>(), resp.get())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use boost::get
instead.
@@ -25,11 +34,24 @@ AcceptanceFixture::AcceptanceFixture() | |||
shared_model::crypto::DefaultCryptoAlgorithmType::generateKeypair()), | |||
kUserKeypair( | |||
shared_model::crypto::DefaultCryptoAlgorithmType::generateKeypair()), | |||
checkEnoughSignatures([](auto &status) { | |||
checkStatus<shared_model::interface::EnoughSignaturesCollectedResponse>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks copy-pasted. Define and instantiate a template variable instead:
template <typename T>
const std::function<void(const shared_model::proto::TransactionResponse &)> check_status = [](const shared_model::proto::TransactionResponse &) {
...
}
template const std::function<void(const shared_model::proto::TransactionResponse &)> check_status<shared_model::interface::EnoughSignaturesCollectedResponse>;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are just comfy aliases to checkStatus itself.
It's much more descriptive:
itf.checkStatus(checkEnoughSignatures)
rather than:
itf.checkStatus(check_status<shared_model::interface::EnoughSignaturesCollectedResponse)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, but is it possible to initialize the variables with the function directly, so that it is not required to wrap checkStatus<T>
in a lambda? This will reduce code in this file at least.
@@ -162,8 +163,18 @@ class AcceptanceFixture : public ::testing::Test { | |||
const shared_model::crypto::Keypair kAdminKeypair; | |||
const shared_model::crypto::Keypair kUserKeypair; | |||
|
|||
const std::function<void(const shared_model::proto::TransactionResponse &)> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like copy-paste. Declare a template variable:
template <typename T>
const std::function<void(const shared_model::proto::TransactionResponse &)> check_status;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can declare the variables with just once type to avoid duplication:
const std::function<void(const TxResponseType &)> checkEnoughSignatures, checkStatelessInvalid, ...
namespace { | ||
template <typename T> | ||
void checkStatus(const shared_model::interface::TransactionResponse &resp) { | ||
ASSERT_NO_THROW( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assertions are better done in the test body, so that log contains a reference to line of test code.
@@ -11,6 +11,7 @@ | |||
#include <string> | |||
#include <vector> | |||
#include "cryptography/keypair.hpp" | |||
#include "framework/integration_framework/integration_test_framework.hpp" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is unused, so it can be removed.
Signed-off-by: Kitsu <[email protected]>
Signed-off-by: Kitsu <[email protected]>
@@ -163,6 +165,12 @@ namespace integration_framework { | |||
log_->info("commit"); | |||
queue_cond.notify_all(); | |||
}); | |||
iroha_instance_->getIrohaInstance()->getStatusBus()->statuses().subscribe( | |||
[this](auto responses) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
responses -> response
const shared_model::interface::types::HashType &tx_hash, | ||
std::function<void(const shared_model::proto::TransactionResponse &)> | ||
validation) { | ||
// fetch first proposal from proposal queue |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment looks out of place, please rephrase appropriately.
@@ -375,6 +383,21 @@ namespace integration_framework { | |||
return *this; | |||
} | |||
|
|||
IntegrationTestFramework &IntegrationTestFramework::checkStatus( | |||
const shared_model::interface::types::HashType &tx_hash, | |||
std::function<void(const shared_model::proto::TransactionResponse &)> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
checkProposal
, checkVerifiedProposal
, checkBlock
use interface type for lambdas. Please use it here as well for consistency:
std::function<void(const TxResponseType &)>
@@ -25,11 +34,24 @@ AcceptanceFixture::AcceptanceFixture() | |||
shared_model::crypto::DefaultCryptoAlgorithmType::generateKeypair()), | |||
kUserKeypair( | |||
shared_model::crypto::DefaultCryptoAlgorithmType::generateKeypair()), | |||
checkEnoughSignatures([](auto &status) { | |||
checkStatus<shared_model::interface::EnoughSignaturesCollectedResponse>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, but is it possible to initialize the variables with the function directly, so that it is not required to wrap checkStatus<T>
in a lambda? This will reduce code in this file at least.
@@ -162,8 +163,18 @@ class AcceptanceFixture : public ::testing::Test { | |||
const shared_model::crypto::Keypair kAdminKeypair; | |||
const shared_model::crypto::Keypair kUserKeypair; | |||
|
|||
const std::function<void(const shared_model::proto::TransactionResponse &)> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can declare the variables with just once type to avoid duplication:
const std::function<void(const TxResponseType &)> checkEnoughSignatures, checkStatelessInvalid, ...
Signed-off-by: Kitsu <[email protected]>
Signed-off-by: Kitsu <[email protected]>
|
||
#define CHECK_COMMITTED \ | ||
[](const shared_model::interface::TransactionResponse &resp) { \ | ||
SCOPED_TRACE("CHECK_COMMITTE"); \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
find&replace ninja failed :( thanks!
Signed-off-by: Kitsu <[email protected]>
Signed-off-by: Kitsu <[email protected]>
} // namespace shared_model | ||
namespace { | ||
template <typename Type> | ||
void __checkFunction( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Codestyle requires camelcase names without underscores for functions. Leading underscores are used by system and compiler methods, so there is no need for them here.
} | ||
|
||
#define CHECK_ENOUGH_SIGNATURES \ | ||
[](const shared_model::interface::TransactionResponse &resp) { \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please separate these macros into two:
#define VALIDATE_RESPONSE(type) \
[](const shared_model::interface::TransactionResponse &resp) { \
SCOPED_TRACE("#type"); \
checkFunction<shared_model::interface::##type>(resp); \
}
#define CHECK_ENOUGH_SIGNATURES VALIDATE_RESPONSE(EnoughSignaturesCollectedResponse)
User proper naming for internal checking repsonse function. Also reuse code in macros. Signed-off-by: Kitsu <[email protected]>
ef112a9
to
f873d2e
Compare
Signed-off-by: Kitsu <[email protected]>
Description of the Change
ITF before only able to check, whether the sent tx is stateless valid or not (only the first status). This RP introduce the ITF feature to check against all the specified statuses, both for single transaction and tx sequence.
Benefits
It is possible to check all statuses with one itf command, their order and responses content (e.g error message)
Possible Drawbacks
Current implementation doesn't check the order of passed transaction. Is it an issue?Usage Examples or Tests
As a usage example CreateRole::Basic acceptance test was reworked according to new ITF::sendTx.
Also for ITF::sendTxSequence there was reworked a fn call in BatchPipelineTest::InvalidAtomicBatch