diff options
author | Kenneth Anthony Giusti <kgiusti@apache.org> | 2010-12-01 20:28:35 +0000 |
---|---|---|
committer | Kenneth Anthony Giusti <kgiusti@apache.org> | 2010-12-01 20:28:35 +0000 |
commit | da185c1a45b6287c0ec79fa6fe8adacdba93bff1 (patch) | |
tree | 6f79d1f7e78bab8852c0668e8fb39f11cfe3d775 /qpid | |
parent | f7efd9e27b96e43bb92844c52a186af1aa62b483 (diff) | |
download | qpid-python-da185c1a45b6287c0ec79fa6fe8adacdba93bff1.tar.gz |
Add a unit_test fixture for the Brokers internal management agent.
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1041150 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid')
-rw-r--r-- | qpid/cpp/src/tests/BrokerFixture.h | 4 | ||||
-rw-r--r-- | qpid/cpp/src/tests/BrokerMgmtAgent.cpp | 319 | ||||
-rw-r--r-- | qpid/cpp/src/tests/BrokerMgmtAgent.xml | 38 | ||||
-rw-r--r-- | qpid/cpp/src/tests/Makefile.am | 2 | ||||
-rw-r--r-- | qpid/cpp/src/tests/MessagingFixture.h | 4 | ||||
-rw-r--r-- | qpid/cpp/src/tests/brokermgmt.mk | 45 | ||||
-rw-r--r-- | qpid/cpp/src/tests/testagent.mk | 2 |
7 files changed, 408 insertions, 6 deletions
diff --git a/qpid/cpp/src/tests/BrokerFixture.h b/qpid/cpp/src/tests/BrokerFixture.h index 29920bb71a..672d954572 100644 --- a/qpid/cpp/src/tests/BrokerFixture.h +++ b/qpid/cpp/src/tests/BrokerFixture.h @@ -48,7 +48,7 @@ struct BrokerFixture : private boost::noncopyable { BrokerPtr broker; qpid::sys::Thread brokerThread; - BrokerFixture(Broker::Options opts=Broker::Options()) { + BrokerFixture(Broker::Options opts=Broker::Options(), bool enableMgmt=false) { // Keep the tests quiet unless logging env. vars have been set by user. if (!::getenv("QPID_LOG_ENABLE") && !::getenv("QPID_TRACE")) { qpid::log::Options logOpts; @@ -58,7 +58,7 @@ struct BrokerFixture : private boost::noncopyable { } opts.port=0; // Management doesn't play well with multiple in-process brokers. - opts.enableMgmt=false; + opts.enableMgmt=enableMgmt; opts.workerThreads=1; opts.dataDir=""; opts.auth=false; diff --git a/qpid/cpp/src/tests/BrokerMgmtAgent.cpp b/qpid/cpp/src/tests/BrokerMgmtAgent.cpp new file mode 100644 index 0000000000..26d62ff952 --- /dev/null +++ b/qpid/cpp/src/tests/BrokerMgmtAgent.cpp @@ -0,0 +1,319 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * 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 + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +#include "unit_test.h" +#include "MessagingFixture.h" +#include "qpid/management/Buffer.h" +#include "qpid/messaging/Message.h" +#include "qpid/amqp_0_10/Codecs.h" + +#include "qmf/org/apache/qpid/broker/mgmt/test/TestObject.h" + + +using qpid::management::Mutex; +using qpid::management::Manageable; +using qpid::management::Buffer; +using namespace qpid::messaging; +using namespace qpid::types; + + + +namespace qpid { + namespace tests { + + namespace _qmf = qmf::org::apache::qpid::broker::mgmt::test; + namespace { + + typedef boost::shared_ptr<_qmf::TestObject> TestObjectPtr; + typedef std::vector<TestObjectPtr> TestObjectVector; + + class AgentFixture + { + MessagingFixture *mFix; + + public: + AgentFixture( unsigned int pubInterval=10, bool qmfV2=false ) + { + qpid::broker::Broker::Options opts = qpid::broker::Broker::Options(); + opts.enableMgmt=true; + opts.qmf2Support=qmfV2; + opts.mgmtPubInterval=pubInterval; + mFix = new MessagingFixture(opts, true); + + _qmf::TestObject::registerSelf(getBrokerAgent()); + }; + ~AgentFixture() + { + delete mFix; + }; + ::qpid::management::ManagementAgent *getBrokerAgent() { return mFix->broker->getManagementAgent(); } + Receiver createV1DataIndRcvr( const std::string package, const std::string klass ) + { + return mFix->session.createReceiver(std::string("kqueue; {create: always, delete: always, " + "node: {type: queue, " + "x-bindings: [{exchange: qpid.management, " + "key: 'console.obj.1.0.") + + package + std::string(".") + klass + + std::string("'}]}}")); + }; + Receiver createV2DataIndRcvr( const std::string package, const std::string klass ) + { + std::string p(package); + std::replace(p.begin(), p.end(), '.', '_'); + std::string k(klass); + std::replace(k.begin(), k.end(), '.', '_'); + + return mFix->session.createReceiver(std::string("kqueue; {create: always, delete: always, " + "node: {type: queue, " + "x-bindings: [{exchange: qmf.default.topic, " + "key: 'agent.ind.data.") + + p + std::string(".") + k + + std::string("'}]}}")); + + }; + }; + + + // A "management object" that supports the TestObject + // + class TestManageable : public qpid::management::Manageable + { + management::ManagementObject* mgmtObj; + public: + TestManageable(management::ManagementAgent *agent) { + _qmf::TestObject *tmp = new _qmf::TestObject(agent, this); + + // see it with some default values... + tmp->set_string1("This is a test string!"); + tmp->set_bool1(true); + qpid::types::Variant::Map vMap; + vMap["one"] = qpid::types::Variant(1); + vMap["two"] = qpid::types::Variant("two"); + vMap["three"] = qpid::types::Variant("whatever"); + tmp->set_map1(vMap); + + mgmtObj = tmp; + }; + ~TestManageable() { mgmtObj = 0; /* deleted by agent on shutdown */ }; + management::ManagementObject* GetManagementObject() const { return mgmtObj; }; + static void validateTestObjectProperties(_qmf::TestObject& to) + { + BOOST_CHECK(to.get_string1() == std::string("This is a test string!")); + BOOST_CHECK(to.get_bool1() == true); + BOOST_CHECK(to.get_map1().size() == 3); + qpid::types::Variant::Map mappy = to.get_map1(); + BOOST_CHECK(1 == (unsigned int)mappy["one"]); + BOOST_CHECK(mappy["two"].asString() == std::string("two")); + BOOST_CHECK(mappy["three"].asString() == std::string("whatever")); + }; + }; + + + // decode a V1 Content Indication message + // + void decodeV1ObjectUpdates(const Message& inMsg, TestObjectVector& objs, const size_t objLen) + { + const size_t MAX_BUFFER_SIZE=65536; + char tmp[MAX_BUFFER_SIZE]; + + objs.clear(); + + BOOST_CHECK(inMsg.getContent().size() <= MAX_BUFFER_SIZE); + + ::memcpy(tmp, inMsg.getContent().data(), inMsg.getContent().size()); + Buffer buf(tmp, inMsg.getContent().size()); + + while (buf.available() > 8) { // 8 == qmf v1 header size + BOOST_CHECK_EQUAL(buf.getOctet(), 'A'); + BOOST_CHECK_EQUAL(buf.getOctet(), 'M'); + BOOST_CHECK_EQUAL(buf.getOctet(), '2'); + BOOST_CHECK_EQUAL(buf.getOctet(), 'c'); // opcode == content indication + // @@todo: kag: how do we skip 'i' entries??? + buf.getLong(); // ignore sequence + + std::string str1; // decode content body as string + buf.getRawData(str1, objLen); + + TestObjectPtr fake(new _qmf::TestObject(0,0)); + fake->readProperties( str1 ); + objs.push_back(fake); + } + } + + + // decode a V2 Content Indication message + // + void decodeV2ObjectUpdates(const qpid::messaging::Message& inMsg, TestObjectVector& objs) + { + objs.clear(); + + BOOST_CHECK_EQUAL(inMsg.getContentType(), std::string("amqp/list")); + + const ::qpid::types::Variant::Map& m = inMsg.getProperties(); + Variant::Map::const_iterator iter = m.find(std::string("qmf.opcode")); + BOOST_CHECK(iter != m.end()); + BOOST_CHECK_EQUAL(iter->second.asString(), std::string("_data_indication")); + + Variant::List vList; + ::qpid::amqp_0_10::ListCodec::decode(inMsg.getContent(), vList); + + for (Variant::List::iterator lIter = vList.begin(); lIter != vList.end(); lIter++) { + TestObjectPtr fake(new _qmf::TestObject(0,0)); + fake->readTimestamps(lIter->asMap()); + fake->mapDecodeValues((lIter->asMap())["_values"].asMap()); + objs.push_back(fake); + } + } + } + + QPID_AUTO_TEST_SUITE(BrokerMgmtAgent) + + // verify that an object that is added to the broker's management database is + // published correctly. Furthermore, verify that it is published once after + // it has been deleted. + // + QPID_AUTO_TEST_CASE(v1ObjPublish) + { + AgentFixture* fix = new AgentFixture(5); + management::ManagementAgent* agent; + agent = fix->getBrokerAgent(); + + // create a manageable test object + TestManageable *tm = new TestManageable(agent); + uint32_t objLen = tm->GetManagementObject()->writePropertiesSize(); + + Receiver r1 = fix->createV1DataIndRcvr("org.apache.qpid.broker.mgmt.test", "#"); + + agent->addObject(tm->GetManagementObject(), "testobj-1"); + + // wait for the object to be published + Message m1; + BOOST_CHECK(r1.fetch(m1, Duration::SECOND * 10)); + + TestObjectVector objs; + decodeV1ObjectUpdates(m1, objs, objLen); + BOOST_CHECK(objs.size() > 0); + + for (TestObjectVector::iterator oIter = objs.begin(); oIter != objs.end(); oIter++) { + + TestManageable::validateTestObjectProperties(**oIter); + + qpid::types::Variant::Map mappy; + (*oIter)->writeTimestamps(mappy); + BOOST_CHECK(0 == mappy["_delete_ts"].asUint64()); // not deleted + } + + // destroy the object + + tm->GetManagementObject()->resourceDestroy(); + + // wait for the deleted object to be published + + bool isDeleted = false; + while (!isDeleted && r1.fetch(m1, Duration::SECOND * 10)) { + + decodeV1ObjectUpdates(m1, objs, objLen); + BOOST_CHECK(objs.size() > 0); + + for (TestObjectVector::iterator oIter = objs.begin(); oIter != objs.end(); oIter++) { + + TestManageable::validateTestObjectProperties(**oIter); + + qpid::types::Variant::Map mappy; + (*oIter)->writeTimestamps(mappy); + if (mappy["_delete_ts"].asUint64() != 0) + isDeleted = true; + } + } + + BOOST_CHECK(isDeleted); + + r1.close(); + delete fix; + delete tm; + } + + // Repeat the previous test, but with V2-based object support + // + QPID_AUTO_TEST_CASE(v2ObjPublish) + { + AgentFixture* fix = new AgentFixture(5, true); + management::ManagementAgent* agent; + agent = fix->getBrokerAgent(); + + TestManageable *tm = new TestManageable(agent); + + Receiver r1 = fix->createV2DataIndRcvr(tm->GetManagementObject()->getPackageName(), "#"); + + agent->addObject(tm->GetManagementObject(), "testobj-1"); + + // wait for the object to be published + Message m1; + BOOST_CHECK(r1.fetch(m1, Duration::SECOND * 10)); + + TestObjectVector objs; + decodeV2ObjectUpdates(m1, objs); + BOOST_CHECK(objs.size() > 0); + + for (TestObjectVector::iterator oIter = objs.begin(); oIter != objs.end(); oIter++) { + + TestManageable::validateTestObjectProperties(**oIter); + + qpid::types::Variant::Map mappy; + (*oIter)->writeTimestamps(mappy); + BOOST_CHECK(0 == mappy["_delete_ts"].asUint64()); + } + + // destroy the object + + tm->GetManagementObject()->resourceDestroy(); + + // wait for the deleted object to be published + + bool isDeleted = false; + while (!isDeleted && r1.fetch(m1, Duration::SECOND * 10)) { + + decodeV2ObjectUpdates(m1, objs); + BOOST_CHECK(objs.size() > 0); + + for (TestObjectVector::iterator oIter = objs.begin(); oIter != objs.end(); oIter++) { + + TestManageable::validateTestObjectProperties(**oIter); + + qpid::types::Variant::Map mappy; + (*oIter)->writeTimestamps(mappy); + if (mappy["_delete_ts"].asUint64() != 0) + isDeleted = true; + } + } + + BOOST_CHECK(isDeleted); + + r1.close(); + delete fix; + delete tm; + } + + QPID_AUTO_TEST_SUITE_END() + } +} + + diff --git a/qpid/cpp/src/tests/BrokerMgmtAgent.xml b/qpid/cpp/src/tests/BrokerMgmtAgent.xml new file mode 100644 index 0000000000..202b8debf3 --- /dev/null +++ b/qpid/cpp/src/tests/BrokerMgmtAgent.xml @@ -0,0 +1,38 @@ +<schema package="org.apache.qpid.broker.mgmt.test"> + +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + 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 + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> + + <!-- + =============================================================== + TestObject + =============================================================== + --> + <class name="TestObject"> + + A test object defined for the BrokerMgmtAgent unit test. + + <property name="string1" type="lstr" access="RW" index="y"/> + <property name="bool1" type="bool" access="RW"/> + <property name="map1" type="map" access="RW"/> + + </class> + +</schema> + diff --git a/qpid/cpp/src/tests/Makefile.am b/qpid/cpp/src/tests/Makefile.am index ca7b89abc7..20df4b456e 100644 --- a/qpid/cpp/src/tests/Makefile.am +++ b/qpid/cpp/src/tests/Makefile.am @@ -20,6 +20,7 @@ AM_CXXFLAGS = $(WARNING_CFLAGS) -DBOOST_TEST_DYN_LINK INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_srcdir)/src -I$(top_builddir)/src PUBLIC_INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include # Use public API only +QMF_GEN=$(top_srcdir)/managementgen/qmf-gen abs_builddir=@abs_builddir@ abs_srcdir=@abs_srcdir@ @@ -400,4 +401,5 @@ clean-local: rm -rf $(CLEAN_LOCAL) include testagent.mk +#include brokermgmt.mk diff --git a/qpid/cpp/src/tests/MessagingFixture.h b/qpid/cpp/src/tests/MessagingFixture.h index 18cdeb1701..715de09bad 100644 --- a/qpid/cpp/src/tests/MessagingFixture.h +++ b/qpid/cpp/src/tests/MessagingFixture.h @@ -97,8 +97,8 @@ struct MessagingFixture : public BrokerFixture messaging::Session session; BrokerAdmin admin; - MessagingFixture(Broker::Options opts = Broker::Options()) : - BrokerFixture(opts), + MessagingFixture(Broker::Options opts = Broker::Options(), bool mgmtEnabled=false) : + BrokerFixture(opts, mgmtEnabled), connection(open(broker->getPort(Broker::TCP_TRANSPORT))), session(connection.createSession()), admin(broker->getPort(Broker::TCP_TRANSPORT)) diff --git a/qpid/cpp/src/tests/brokermgmt.mk b/qpid/cpp/src/tests/brokermgmt.mk new file mode 100644 index 0000000000..ad73da4717 --- /dev/null +++ b/qpid/cpp/src/tests/brokermgmt.mk @@ -0,0 +1,45 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# 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 +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +# Build a simple qmf agent for test purposes. + +BROKERMGMT_GEN_SRC= \ + brokermgmt_gen/qmf/org/apache/qpid/broker/mgmt/test/TestObject.h \ + brokermgmt_gen/qmf/org/apache/qpid/broker/mgmt/test/Package.cpp \ + brokermgmt_gen/qmf/org/apache/qpid/broker/mgmt/test/Package.h \ + brokermgmt_gen/qmf/org/apache/qpid/broker/mgmt/test/TestObject.cpp \ + brokermgmt_gen/qmf/org/apache/qpid/broker/mgmt/test/ArgsTestObjectMethod1.h + +$(BROKERMGMT_GEN_SRC): brokermgmt_gen.timestamp + +if GENERATE +BROKERMGMT_DEPS=../mgen.timestamp +endif # GENERATE +brokermgmt_gen.timestamp: BrokerMgmtAgent.xml ${BROKERMGMT_DEPS} + $(QMF_GEN) -b -o brokermgmt_gen/qmf $(srcdir)/BrokerMgmtAgent.xml + touch $@ + +BrokerMgmtAgent.$(OBJEXT): $(BROKERMGMT_GEN_SRC) + +CLEANFILES+=$(BROKERMGMT_GEN_SRC) brokermgmt_gen.timestamp + +unit_test_SOURCES+=BrokerMgmtAgent.cpp ${BROKERMGMT_GEN_SRC} +INCLUDES+= -Ibrokermgmt_gen + +EXTRA_DIST+=BrokerMgmtAgent.xml diff --git a/qpid/cpp/src/tests/testagent.mk b/qpid/cpp/src/tests/testagent.mk index 0f171d9579..19d91ccab9 100644 --- a/qpid/cpp/src/tests/testagent.mk +++ b/qpid/cpp/src/tests/testagent.mk @@ -19,8 +19,6 @@ # Build a simple qmf agent for test purposes. -QMF_GEN=$(top_srcdir)/managementgen/qmf-gen - TESTAGENT_GEN_SRC= \ testagent_gen/qmf/org/apache/qpid/agent/example/Parent.h \ testagent_gen/qmf/org/apache/qpid/agent/example/Child.h \ |