1 /*--------------------------------------------------------------------------
  2 Name:      TestRam.cpp
  3 Project:   xmlBlaster.org
  4 Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file
  5 Comment:   Load test for xmlBlaster
  6 Version:   $Id: TestRam.cpp 14955 2006-03-20 12:40:31Z goetzger $
  7 ---------------------------------------------------------------------------*/
  8 #include <util/XmlBCfg.h>
  9 #include "TestSuite.h"
 10 #include <util/StopWatch.h>
 11 #include <iostream>
 12 
 13 using namespace std;
 14 using namespace org::xmlBlaster::client;
 15 using namespace org::xmlBlaster::util;
 16 using namespace org::xmlBlaster::util::qos;
 17 using namespace org::xmlBlaster::authentication;
 18 using namespace org::xmlBlaster::client::key;
 19 using namespace org::xmlBlaster::client::qos;
 20 
 21 
 22 /**
 23  * This client publishes 1000 different messages to measure RAM
 24  * consumption/message. <br />
 25  * The RAM consumption in kByte/Message is logged to the console.  <br />
 26  * Note that this is the net RAM consumption, without any content and a very
 27  * small XmlKey. You may see this as the internal memory overhead in
 28  * xmlBlaster for each published message. <br />
 29  * This client may be invoked multiple time on the same xmlBlaster server,
 30  * as it cleans up everything after his tests are done. <p>
 31  */
 32 
 33 namespace org { namespace xmlBlaster { namespace test {
 34 
 35 /**
 36  * Constructs the TestRam object.
 37  * <p />
 38  * @param testName  The name used in the test suite
 39  * @param loginName The name to login to the xmlBlaster
 40  */
 41 
 42 class TestRam : public TestSuite
 43 {
 44 
 45 private:
 46 
 47    static const string::size_type NUM_PUBLISH = 1000;
 48    StopWatch stopWatch_;
 49    string    publishOid_;
 50    string    senderName_;
 51    string    senderContent_;
 52    string    contentMime_;
 53    string    contentMimeExtended_;
 54 
 55 public:
 56    TestRam(int args, char *argc[], const string &loginName) 
 57       :  TestSuite(args, argc, "TestRam"), stopWatch_()
 58    {
 59       senderName_   = loginName;
 60       publishOid_   = "";
 61       contentMime_  = "text/plain";
 62       contentMimeExtended_ = "1.0";
 63    }
 64 
 65    ~TestRam() {
 66    }
 67 
 68 
 69    /**
 70     * Sets up the fixture.
 71     * <p />
 72     * Connect to xmlBlaster and login
 73     */
 74    void setUp() 
 75    {
 76       TestSuite::setUp();
 77       try {
 78          string passwd = "secret";
 79          SecurityQos secQos(global_, senderName_, passwd);
 80          ConnectQos connQos(global_);
 81          connQos.setSecurityQos(secQos);
 82          connection_.connect(connQos, 0);
 83           // Connect to xmlBlaster without Callback
 84       }
 85       catch (XmlBlasterException &e) {
 86           log_.error(ME, e.toXml());
 87           usage();
 88       }
 89    }
 90 
 91 
 92    /**
 93     * Tears down the fixture.
 94     * <p />
 95     * cleaning up .... erase() the previous message OID and logout
 96     */
 97    void tearDown() 
 98    {
 99       log_.info(ME, "tearDown() ...");
100 
101       for (string::size_type i=0; i < NUM_PUBLISH; i++) {
102          EraseKey key(global_);
103          key.setOid(string("TestRam-") + lexical_cast<string>(i+1));
104          EraseQos qos(global_);
105          vector<EraseReturnQos> strArr;
106          try {
107             strArr = connection_.erase(key, qos);
108             if (strArr.size() != 1) {
109                log_.error(ME, "num erased messages is wrong");
110                assert(0);
111             }
112          }
113          catch(XmlBlasterException &e) {
114             log_.error(ME, string("XmlBlasterException: ") + e.toXml());
115          }
116       }
117       log_.info(ME, "Erased " + lexical_cast<string>(NUM_PUBLISH) + " topics");
118 
119       connection_.disconnect(DisconnectQos(global_));
120    }
121 
122 
123    /**
124     * TEST: Construct a message and publish it.
125     * <p />
126     * The returned publishOid is checked
127     */
128    void testPublish() 
129    {
130       if (log_.trace()) log_.trace(ME, "Publishing new topics ...");
131 
132       vector<util::MessageUnit> msgVec;
133       msgVec.reserve(NUM_PUBLISH);
134 
135       for (string::size_type i=0; i < NUM_PUBLISH; i++) {
136          PublishKey key(global_);
137          key.setOid(string("TestRam-") + lexical_cast<string>(i+1));
138          senderContent_ = lexical_cast<string>(i+1);
139          PublishQos qos(global_);
140          util::MessageUnit msgUnit(key, senderContent_, qos);
141          msgVec.push_back(msgUnit);
142       }
143 
144       try {
145          // 1. Query the current memory allocated in xmlBlaster
146          GetKey key(global_);
147          key.setOid("__cmd:?usedMem");
148          GetQos qos(global_);
149          vector<util::MessageUnit> msgRetVec = connection_.get(key, qos);
150          if (msgRetVec.size() != 1) {
151             log_.error(ME, "msgRetVec.length!=1");
152             assert(0);
153          }
154          if (msgRetVec[0].getContentLen() == 0) {
155             log_.error(ME, "returned msgRetVec[0].msgUnit.content.length == 0");
156             assert(0);
157          }
158          string usedMemBefore = msgRetVec[0].getContentStr();
159          long usedBefore = lexical_cast<long>(usedMemBefore);
160          log_.info(ME, string("xmlBlaster used allocated memory before ") +
161                    "publishing = " + usedMemBefore);
162 
163          log_.info(ME, "Publishing " + lexical_cast<string>(NUM_PUBLISH) + " new topics ...");
164          stopWatch_.restart();
165          // 2. publish all the messages
166          vector<PublishReturnQos> publishOidArr = connection_.publishArr(msgVec);
167          double elapsed = 0.001 * stopWatch_.elapsed();
168 
169          for (unsigned int i=0; i < NUM_PUBLISH; i++) {
170             cout << msgVec[i].getKey().toXml() << endl;
171             //cout << msgVec[i].getContentStr() << endl;
172          }
173 
174          long avg = (long)((double)NUM_PUBLISH / elapsed);
175          log_.info(ME, "Success: Publishing done, " + lexical_cast<string>(NUM_PUBLISH) + " messages sent, average new topics/second = " + lexical_cast<string>(avg));
176 
177          if (publishOidArr.size() != NUM_PUBLISH) {
178             log_.error(ME, "numPublished=" + lexical_cast<string>(publishOidArr.size()) + " is wrong");
179             assert(0);
180          }
181 
182          // 3. Query the memory allocated in xmlBlaster after publishing all
183          // the messages
184          msgRetVec = connection_.get(key, qos);
185          string usedMemAfter = msgRetVec[0].getContentStr();
186          long usedAfter = lexical_cast<long>(usedMemAfter);
187          log_.info(ME, string("xmlBlaster used allocated memory after ") +
188                    "publishing = " + usedMemAfter);
189          log_.info(ME, lexical_cast<string>((usedAfter-usedBefore)/NUM_PUBLISH) + " bytes/topic");
190       }
191       catch(XmlBlasterException &e) {
192          log_.warn(ME, string("Exception: ") + e.toXml());
193          assert(0);
194       }
195    }
196 
197 
198    /**
199     * TEST: Construct 1000 messages and publish it.
200     */
201    void testManyPublish() 
202    {
203       testPublish();
204    }
205 
206    void usage() const
207    {
208                 TestSuite::usage();
209       log_.plain(ME, "----------------------------------------------------------");
210       log_.plain(ME, "Testing C++ access to xmlBlaster");
211       log_.plain(ME, "Usage:");
212       XmlBlasterAccess::usage();
213       log_.usage();
214       log_.plain(ME, "Example:");
215       log_.plain(ME, "   TestRam -bootstrapHostname myHostName");
216       log_.plain(ME, "----------------------------------------------------------");
217    }
218 };
219 
220 }}} // namespace
221 
222 using namespace org::xmlBlaster::test;
223 
224 int main(int args, char *argc[]) {
225    org::xmlBlaster::util::Object_Lifetime_Manager::init();
226    try {
227       TestRam testObj(args, argc, "Tim");
228       testObj.setUp();
229       testObj.testManyPublish();
230       testObj.tearDown();
231    }
232    catch (...) {
233       std::cout << "ERROR: Caught exception!!!!" << endl;
234    }
235    org::xmlBlaster::util::Object_Lifetime_Manager::fini();
236    return 0;
237 }


syntax highlighted by Code2HTML, v. 0.9.1