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