summaryrefslogtreecommitdiff
path: root/cpp/src/tests/txtest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/tests/txtest.cpp')
-rw-r--r--cpp/src/tests/txtest.cpp115
1 files changed, 66 insertions, 49 deletions
diff --git a/cpp/src/tests/txtest.cpp b/cpp/src/tests/txtest.cpp
index f0e70e83e9..d0ba2f1245 100644
--- a/cpp/src/tests/txtest.cpp
+++ b/cpp/src/tests/txtest.cpp
@@ -7,9 +7,9 @@
* to you 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
@@ -33,12 +33,17 @@
#include "qpid/client/SubscriptionManager.h"
#include "qpid/framing/Array.h"
#include "qpid/framing/Buffer.h"
+#include "qpid/framing/Uuid.h"
+#include "qpid/sys/Thread.h"
using namespace qpid;
using namespace qpid::client;
using namespace qpid::sys;
using std::string;
+namespace qpid {
+namespace tests {
+
typedef std::vector<std::string> StringSet;
struct Args : public qpid::TestOptions {
@@ -51,13 +56,14 @@ struct Args : public qpid::TestOptions {
uint txCount;
uint totalMsgCount;
bool dtx;
+ bool quiet;
- Args() : init(true), transfer(true), check(true),
- size(256), durable(true), queues(2),
+ Args() : init(true), transfer(true), check(true),
+ size(256), durable(true), queues(2),
base("tx-test"), msgsPerTx(1), txCount(1), totalMsgCount(10),
- dtx(false)
+ dtx(false), quiet(false)
{
- addOptions()
+ addOptions()
("init", optValue(init, "yes|no"), "Declare queues and populate one with the initial set of messages.")
("transfer", optValue(transfer, "yes|no"), "'Move' messages from one queue to another using transactions to ensure no message loss.")
@@ -69,7 +75,8 @@ struct Args : public qpid::TestOptions {
("messages-per-tx", optValue(msgsPerTx, "N"), "number of messages transferred per transaction")
("tx-count", optValue(txCount, "N"), "number of transactions per 'agent'")
("total-messages", optValue(totalMsgCount, "N"), "total number of messages in 'circulation'")
- ("dtx", optValue(dtx, "yes|no"), "use distributed transactions");
+ ("dtx", optValue(dtx, "yes|no"), "use distributed transactions")
+ ("quiet", optValue(quiet), "reduce output from test");
}
};
@@ -79,7 +86,7 @@ std::string generateData(uint size)
{
if (size < chars.length()) {
return chars.substr(0, size);
- }
+ }
std::string data;
for (uint i = 0; i < (size / chars.length()); i++) {
data += chars;
@@ -99,18 +106,18 @@ void generateSet(const std::string& base, uint count, StringSet& collection)
Args opts;
-struct Client
+struct Client
{
Connection connection;
AsyncSession session;
- Client()
+ Client()
{
opts.open(connection);
session = connection.newSession();
}
- ~Client()
+ ~Client()
{
try{
session.close();
@@ -126,38 +133,44 @@ struct Transfer : public Client, public Runnable
std::string src;
std::string dest;
Thread thread;
- unsigned long xid_cnt;
framing::Xid xid;
- Transfer(const std::string& to, const std::string& from) : src(to), dest(from), xid_cnt(0), xid(0x4c414e47, "", from) {}
+ Transfer(const std::string& to, const std::string& from) : src(to), dest(from), xid(0x4c414e47, "", from) {}
- void run()
+ void run()
{
try {
-
+
if (opts.dtx) session.dtxSelect();
else session.txSelect();
SubscriptionManager subs(session);
-
- LocalQueue lq(AckPolicy(0));//manual acking
- subs.setFlowControl(opts.msgsPerTx, SubscriptionManager::UNLIMITED, true);
- subs.subscribe(lq, src);
-
+
+ LocalQueue lq;
+ SubscriptionSettings settings(FlowControl::messageWindow(opts.msgsPerTx));
+ settings.autoAck = 0; // Disabled
+ Subscription sub = subs.subscribe(lq, src, settings);
+
for (uint t = 0; t < opts.txCount; t++) {
Message in;
Message out("", dest);
if (opts.dtx) {
- setNextXid(xid);
+ setNewXid(xid);
session.dtxStart(arg::xid=xid);
}
for (uint m = 0; m < opts.msgsPerTx; m++) {
in = lq.pop();
- out.setData(in.getData());
+ std::string& data = in.getData();
+ if (data.size() != opts.size) {
+ std::ostringstream oss;
+ oss << "Message size incorrect: size=" << in.getData().size() << "; expected " << opts.size;
+ throw std::runtime_error(oss.str());
+ }
+ out.setData(data);
out.getMessageProperties().setCorrelationId(in.getMessageProperties().getCorrelationId());
out.getDeliveryProperties().setDeliveryMode(in.getDeliveryProperties().getDeliveryMode());
session.messageTransfer(arg::content=out, arg::acceptMode=1);
}
- lq.getAckPolicy().ackOutstanding(session);
+ sub.accept(sub.getUnaccepted());
if (opts.dtx) {
session.dtxEnd(arg::xid=xid);
session.dtxPrepare(arg::xid=xid);
@@ -171,14 +184,13 @@ struct Transfer : public Client, public Runnable
}
}
- void setNextXid(framing::Xid& xid) {
- std::ostringstream oss;
- oss << std::setfill('0') << std::hex << "xid-" << std::setw(12) << (++xid_cnt);
- xid.setGlobalId(oss.str());
+ void setNewXid(framing::Xid& xid) {
+ framing::Uuid uuid(true);
+ xid.setGlobalId(uuid.str());
}
};
-struct Controller : public Client
+struct Controller : public Client
{
StringSet ids;
StringSet queues;
@@ -189,7 +201,7 @@ struct Controller : public Client
generateSet("msg", opts.totalMsgCount, ids);
}
- void init()
+ void init()
{
//declare queues
for (StringSet::iterator i = queues.begin(); i != queues.end(); i++) {
@@ -217,7 +229,7 @@ struct Controller : public Client
StringSet::iterator next = i + 1;
if (next == queues.end()) next = queues.begin();
- std::cout << "Transfering from " << *i << " to " << *next << std::endl;
+ if (!opts.quiet) std::cout << "Transfering from " << *i << " to " << *next << std::endl;
agents.push_back(new Transfer(*i, *next));
agents.back().thread = Thread(agents.back());
}
@@ -227,11 +239,9 @@ struct Controller : public Client
}
}
- void check()
+ int check()
{
SubscriptionManager subs(session);
- subs.setFlowControl(SubscriptionManager::UNLIMITED, SubscriptionManager::UNLIMITED, false);
- subs.setAcceptMode(1/*not-required*/);
// Recover DTX transactions (if any)
if (opts.dtx) {
@@ -241,13 +251,13 @@ struct Controller : public Client
xidArr.collect(inDoubtXids);
if (inDoubtXids.size()) {
- std::cout << "Recovering DTX in-doubt transaction(s):" << std::endl;
+ if (!opts.quiet) std::cout << "Recovering DTX in-doubt transaction(s):" << std::endl;
framing::StructHelper decoder;
framing::Xid xid;
// abort even, commit odd transactions
for (unsigned i = 0; i < inDoubtXids.size(); i++) {
decoder.decode(xid, inDoubtXids[i]);
- std::cout << (i%2 ? " * aborting " : " * committing ");
+ if (!opts.quiet) std::cout << (i%2 ? " * aborting " : " * committing ");
xid.print(std::cout);
std::cout << std::endl;
if (i%2) {
@@ -262,9 +272,10 @@ struct Controller : public Client
StringSet drained;
//drain each queue and verify the correct set of messages are available
for (StringSet::iterator i = queues.begin(); i != queues.end(); i++) {
- //subscribe, allocate credit and flush
- LocalQueue lq(AckPolicy(0));//manual acking
- subs.subscribe(lq, *i, *i);
+ //subscribe, allocate credit and flushn
+ LocalQueue lq;
+ SubscriptionSettings settings(FlowControl::unlimited(), ACCEPT_MODE_NONE);
+ subs.subscribe(lq, *i, settings);
session.messageFlush(arg::destination=*i);
session.sync();
@@ -275,7 +286,7 @@ struct Controller : public Client
drained.push_back(m.getMessageProperties().getCorrelationId());
++count;
}
- std::cout << "Drained " << count << " messages from " << *i << std::endl;
+ if (!opts.quiet) std::cout << "Drained " << count << " messages from " << *i << std::endl;
}
sort(ids.begin(), ids.end());
@@ -283,41 +294,47 @@ struct Controller : public Client
//check that drained == ids
StringSet missing;
- set_difference(ids.begin(), ids.end(), drained.begin(), drained.end(), back_inserter(missing));
+ set_difference(ids.begin(), ids.end(), drained.begin(), drained.end(), back_inserter(missing));
StringSet extra;
- set_difference(drained.begin(), drained.end(), ids.begin(), ids.end(), back_inserter(extra));
+ set_difference(drained.begin(), drained.end(), ids.begin(), ids.end(), back_inserter(extra));
if (missing.empty() && extra.empty()) {
- std::cout << "All expected messages were retrieved." << std::endl;
+ std::cout << "All expected messages were retrieved." << std::endl;
+ return 0;
} else {
if (!missing.empty()) {
std::cout << "The following ids were missing:" << std::endl;
for (StringSet::iterator i = missing.begin(); i != missing.end(); i++) {
- std::cout << " '" << *i << "'" << std::endl;
- }
+ std::cout << " '" << *i << "'" << std::endl;
+ }
}
if (!extra.empty()) {
std::cout << "The following extra ids were encountered:" << std::endl;
for (StringSet::iterator i = extra.begin(); i != extra.end(); i++) {
- std::cout << " '" << *i << "'" << std::endl;
- }
+ std::cout << " '" << *i << "'" << std::endl;
+ }
}
+ return 1;
}
}
};
+}} // namespace qpid::tests
+
+using namespace qpid::tests;
+
int main(int argc, char** argv)
{
try {
opts.parse(argc, argv);
Controller controller;
- if (opts.init) controller.init();
+ if (opts.init) controller.init();
if (opts.transfer) controller.transfer();
- if (opts.check) controller.check();
+ if (opts.check) return controller.check();
return 0;
} catch(const std::exception& e) {
std::cout << e.what() << std::endl;
}
- return 1;
+ return 2;
}