-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmain.cpp
More file actions
196 lines (156 loc) · 6.47 KB
/
main.cpp
File metadata and controls
196 lines (156 loc) · 6.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
/*
* Copyright (c) 2011 Tobias Markmann
* Licensed under the GNU General Public License v3.
* See gpl-3.0.txt for more information.
*/
#include <fstream>
#include <iostream>
#include <vector>
#include <boost/format.hpp>
#include <boost/program_options.hpp>
// #include <boost/thread.hpp>
// #include <Swiften/EventLoop/SimpleEventLoop.h>
#define private public // FIXME
#include <Swiften/EventLoop/BoostASIOEventLoop.h>
#define private private
#include <Swiften/JID/JID.h>
#include <Swiften/Network/BoostNetworkFactories.h>
#include "AccountDataProvider.h"
#include "LatencyWorkloadBenchmark.h"
#include "BenchmarkNetworkFactories.h"
// #include "BoostEventLoop.h"
#include <ctime>
#include <boost/date_time/microsec_time_clock.hpp>
#include <boost/date_time/posix_time/ptime.hpp>
#define XMPPENCH_VERSION_STRING "0.1"
using namespace Swift;
namespace po = boost::program_options;
class ContinuousAccountProivder : public AccountDataProvider {
public:
ContinuousAccountProivder(const std::string& hostname, const std::string& rabbitprefix) : hostname(hostname), rabbitprefix(rabbitprefix), counter(0) { }
virtual Account getAccount() {
std::string jid = boost::str( boost::format("%1%%2%@%3%") % rabbitprefix % counter % hostname );
std::string password = boost::str( boost::format("%1%%2%") % rabbitprefix % counter);
++counter;
AccountDataProvider::Account acc;
acc.jid = jid;
acc.password = password;
return acc;
}
private:
std::string hostname;
std::string rabbitprefix;
unsigned long counter;
};
void eventLoopRunner(BoostASIOEventLoop* eventLoop) {
eventLoop->ioService_->run();
}
int main(int argc, char *argv[]) {
std::string hostname;
std::string ip;
std::string bodyfile;
std::string rabbitprefix;
bool waitAtBeginning;
size_t jobs = 1;
std::string boshHost;
std::string boshPath;
int boshPort;
bool boshHTTPS;
LatencyWorkloadBenchmark::Options options;
po::options_description desc("Allowed options");
desc.add_options()
("actives", po::value<int>(&options.noOfActiveSessions)->default_value(2000), "number of active connections")
("bodyfile", po::value<std::string>(&bodyfile), "file to read the (unchecked!) body message from")
("help", "produce help message")
("hostname", po::value<std::string>(&hostname)->default_value("localhost"), "hostname of benchmarked server")
("idles", po::value<int>(&options.noOfIdleSessions)->default_value(8000), "number of idle connections")
("ip", po::value<std::string>(&ip), "specify the IP to connect to; overrides DNS lookups; required with jobs > 1")
("jobs", po::value<size_t>(&jobs)->default_value(1), "number of threads to run ! EXPERIMENTAL !")
("nocomp", po::value<bool>(&options.noCompression)->default_value(false), "prevent use of stream compression")
("notls", po::value<bool>(&options.noTLS)->default_value(false), "prevent use of TLS")
("plogins", po::value<size_t>(&options.parallelLogins)->default_value(2), "number of parallel logins")
("rabbitprefix", po::value<std::string>(&rabbitprefix), "Prefix to use before number for accounts and passwords")
("stanzas", po::value<int>(&options.stanzasPerConnection)->default_value(1000), "stanzas to send per connection")
("version", "print version number")
("waitatstart", po::value<bool>(&waitAtBeginning)->default_value(0), "waits at the beginning on keyboard input")
("wcstanzas", po::value<int>(&options.warmupStanzas)->default_value(0), "warm up/cool down stanzas")
("boshhost", po::value<std::string>(&boshHost), "specify to use BOSH for connection, via this host")
("boshport", po::value<int>(&boshPort)->default_value(5280), "specify to change the BOSH port (when using BOSH)")
("boshpath", po::value<std::string>(&boshPath)->default_value("http-bind/"), "specify to change the path used, if using BOSH")
("boshhttps", "use HTTPS (not HTTP) for BOSH")
;
po::variables_map vm;
po::parsed_options parsed = po::command_line_parser(argc, argv).options(desc).allow_unregistered().run();
std::vector<std::string> unrecognizedOptions = collect_unrecognized(parsed.options, boost::program_options::include_positional);
if (!unrecognizedOptions.empty()) {
std::cout << "Unrecognized options!" << std::endl;
std::cout << desc << std::endl;
return 1;
}
po::store(parsed, vm);
po::notify(vm);
if (vm.count("help")) {
std::cout << desc << "\n";
return 1;
}
if (vm.count("version")) {
std::cout << "xmppench - XMPP server benchmarking - Version " << XMPPENCH_VERSION_STRING << std::endl;
return 1;
}
boshHTTPS = vm.count("boshhttps");
if (waitAtBeginning) {
char c;
std::cin >> c;
}
if (jobs > 1 && ip.empty()) {
std::cout << "Error: You have to specify the IP of the server (use --ip) if jobs is greater than 1." << std::endl;
return 1;
}
if (jobs > 1) {
std::cout << "Warning: Running multiple worker threads is an experimental feature." << std::endl;
}
if (options.parallelLogins < jobs) {
options.parallelLogins = jobs;
}
if (!boshHost.empty()) {
options.boshURL = URL(boshHTTPS ? "https" : "http", boshHost, boshPort, boshPath);
}
if (!bodyfile.empty()) {
std::ifstream inputStream(bodyfile.c_str(), std::ios::in | std::ios::binary | std::ios::ate);
std::ifstream::pos_type fSize = inputStream.tellg();
inputStream.seekg(0, std::ios::beg);
std::vector<char> bytes(fSize);
inputStream.read(&bytes[0], fSize);
options.bodymessage = std::string(&bytes[0], fSize);
} else {
options.bodymessage = "Hey. You forgot to specify a body message.";
}
std::vector<BoostASIOEventLoop*> eventLoops;
std::vector<NetworkFactories*> networkFactories;
for (int n = 0; n < jobs; ++n) {
BoostASIOEventLoop* eventLoop = new BoostASIOEventLoop(std::make_shared<boost::asio::io_service>());
NetworkFactories* factory;
//if (jobs > 1) {
factory = new BenchmarkNetworkFactories(eventLoop, ip);
//} else {
// factory = new BoostNetworkFactories(eventLoop);
//}
eventLoops.push_back(eventLoop);
networkFactories.push_back(factory);
}
ContinuousAccountProivder accountProvider(hostname, rabbitprefix);
LatencyWorkloadBenchmark benchmark(networkFactories, &accountProvider, options);
std::vector<std::thread> threadGroup;
for (size_t n = 0; n < jobs; ++n) {
auto service = eventLoops[n]->ioService_;
threadGroup.emplace_back([service](){service->run();});
}
for (auto& thread : threadGroup) {
thread.join();
}
for (size_t i = 0; i < jobs; ++i) {
delete eventLoops[i];
delete networkFactories[i];
}
return 0;
}