Step 1: Move vm scripts to the right place
[integration/test.git] / tools / wcbench / README.md
1 ## Wrapped CBench (WCBench)
2
3 CBench, wrapped in stuff that makes it useful.
4
5 - [Wrapped CBench (WCBench)](#user-content-wrapped-cbench-wcbench)
6     - [Overview](#user-content-overview)
7     - [Usage](#user-content-usage)
8         - [Usage Overview](#user-content-usage-overview)
9         - [Usage Details: wcbench.sh](#user-content-usage-details-wcbenchsh)
10         - [Usage Details: loop_wcbench.sh](#user-content-usage-details-loop_wcbenchsh)
11         - [Usage Details: stats.py](#user-content-usage-details-statspy)
12     - [WCBench Results](#user-content-wcbench-results)
13     - [Detailed Walkthrough: Vagrant](#user-content-detailed-walkthrough-vagrant)
14     - [Detailed Walkthrough: Manual](#user-content-detailed-walkthrough-manual)
15     - [Contributing](#user-content-contributing)
16     - [Contact](#user-content-contact)
17
18 ### Overview
19
20 CBench is a somewhat classic SDN controller benchmark tool. It blasts a controller with OpenFlow packet-in messages and counts the rate of flow mod messages returned. WCBench consumes CBench as a library, then builds a robust test automation, stats collection and stats analysis/graphing system around it.
21
22 WCBench currently only supports the Helium release of the OpenDaylight SDN controller, but it would be fairly easy to add support for other controllers. Community contributions are encouraged!
23
24 ### Usage
25
26 #### Usage Overview
27
28 The help outputs produced by `./wcbench.sh -h`, `./loop_wcbench.sh -h` and `stats.py -h` are quite useful:
29
30 ```
31 Usage ./wcbench.sh [options]
32
33 Setup and/or run CBench and/or OpenDaylight.
34
35 OPTIONS:
36     -h Show this message
37     -v Output verbose debug info
38     -c Install CBench
39     -t <time> Run CBench for given number of minutes
40     -r Run CBench against OpenDaylight
41     -i Install OpenDaylight Helium 0.2.1
42     -p <processors> Pin ODL to given number of processors
43     -o Start and configure OpenDaylight Helium 0.2.1
44     -k Kill OpenDaylight
45     -d Delete local ODL and CBench code
46 ```
47
48 ```
49 Usage ./loop_wcbench.sh [options]
50
51 Run WCBench against OpenDaylight in a loop.
52
53 OPTIONS:
54     -h Show this help message
55     -v Output verbose debug info
56     -l Loop WCBench runs without restarting ODL
57     -r Loop WCBench runs, restart ODL between runs
58     -t <time> Run WCBench for a given number of minutes
59     -p <processors> Pin ODL to given number of processors
60 ```
61
62 ```
63 usage: stats.py [-h] [-S]
64                 [-s {five_load,ram,steal_time,one_load,iowait,fifteen_load,runtime,flows} [{five_load,ram,steal_time,one_load,iowait,fifteen_load,runtime,flows} ...]]
65                 [-G]
66                 [-g {five_load,ram,steal_time,one_load,iowait,fifteen_load,runtime,flows} [{five_load,ram,steal_time,one_load,iowait,fifteen_load,runtime,flows} ...]]
67
68 Compute stats about CBench data
69
70 optional arguments:
71   -h, --help            show this help message and exit
72   -S, --all-stats       compute all stats
73   -s {five_load,ram,steal_time,one_load,iowait,fifteen_load,runtime,flows} [{five_load,ram,steal_time,one_load,iowait,fifteen_load,runtime,flows} ...], --stats {five_load,ram,steal_time,one_load,iowait,fifteen_load,runtime,flows} [{five_load,ram,steal_time,one_load,iowait,fifteen_load,runtime,flows} ...]
74                         compute stats on specified data
75   -G, --all-graphs      graph all data
76   -g {five_load,ram,steal_time,one_load,iowait,fifteen_load,runtime,flows} [{five_load,ram,steal_time,one_load,iowait,fifteen_load,runtime,flows} ...], --graphs {five_load,ram,steal_time,one_load,iowait,fifteen_load,runtime,flows} [{five_load,ram,steal_time,one_load,iowait,fifteen_load,runtime,flows} ...]
77                         graph specified data
78 ```
79
80 #### Usage Details: wcbench.sh
81
82 Most of the work in WCBench happens in `wcbench.sh`. It's the bit that directly wraps CBench, automates CBench/ODL installation, collects system stats, starts/stops ODL, and runs CBench against ODL.
83
84 In more detail, the `wcbench.sh` script supports:
85
86 * Trivially cloning, building and installing CBench via the [oflops repo](https://github.com/andi-bigswitch/oflops).
87 * Changing a set of CBench params (MS_PER_TEST, TEST_PER_SWITCH and CBENCH_WARMUP) to easily set the overall length of a CBench run in minutes. Long CBench runs typically produce results with a lower standard deviation.
88 * Running CBench against an instance of OpenDaylight. The CBench and ODL processes can be on the same machine or different machines. Change the `CONTROLLER_IP` and `CONTROLLER_PORT` variables in `wcbench.sh` to point CBench at the correct ODL process. To run against a local ODL process that's on the default port, set `CONTROLLER_IP="localhost"` and `CONTROLLER_PORT=6633`. To run CBench against a remote ODL process, set `CONTROLLER_IP` to the IP address of the machine running ODL and `CONTROLLER_PORT` to the port ODL is listening on. Obviously the two machines have to have network connectivity with each other. Additionally, since WCBench connects to the remote machine to pull system stats, the remote machine needs to have sshd running and properly configured. The local machine should have its `~/.ssh/config` file and public keys setup such that `ssh $SSH_HOSTNAME` works without a password or RSA unknown-key prompt. To do this, setup something like the following in `~/.ssh/config`:
89
90 ```
91 Host cbench
92     Hostname 209.132.178.170
93     User fedora
94     IdentityFile /home/daniel/.ssh/id_rsa_nopass
95     StrictHostKeyChecking no
96 ```
97
98 As you likely know, `ssh-copy-id` can help you setup your system to connect with the remote box via public key crypto. If you don't have keys setup for public key crypto, google for guides (very out of scope). Finally, note that the `SSH_HOSTNAME` var in `wcbench.sh` must be set to the exact same value given on the `Host` line above.
99 * Trivially installing/configuring ODL from the last successful build (via an Integration team Jenkins job).
100 * Pinning the OpenDaylight process to a given number of CPU cores. This is useful for ensuring that ODL is properly pegged, working as hard as it can with given resource limits. It can also expose bad ODL behavior that comes about when the process is pegged.
101 * Running OpenDaylight and issuing all of the required configurations.
102 * Stopping the OpenDaylight process. This is done cleanly via the `run.sh` script, not `kill` or `pkill`.
103 * Cleaning up everything changed by the `wcbench.sh` script, including deleting ODL and CBench sources and binaries.
104
105
106 #### Usage Details: loop_wcbench.sh
107
108 The `loop_wcbench.sh` script is a fairly simple wrapper around `wcbench.sh` ("I hear you like wrappers, so I wrapped your wrapper in a wrapper"). Its reason for existing is to enable long series of repeated WCBench runs. As described in the [WCBench Results](https://github.com/dfarrell07/cbench_regression#wcbench-results) section, these results will be stored in a CSV file and can be analyzed with `stats.py`, as described in the [Usage Details: stats.py](https://github.com/dfarrell07/cbench_regression#usage-details-statspy) section. Doing many WCBench runs allows trends over time to be observed (like decreasing perf or increasing RAM). More results can also yield more representative stats.
109
110 In more detail, the `loop_wcbench.sh` script supports:
111
112 * Repeatedly running WCBench against ODL without restarting ODL between runs. This test revealed the perf degradation over time described in [bug 1395](https://bugs.opendaylight.org/show_bug.cgi?id=1395).
113 * Repeatedly running WCBench against ODL, restarting ODL between runs. This acted as a control when finding [bug 1395](https://bugs.opendaylight.org/show_bug.cgi?id=1395), as restarting ODL between runs mitigated perf decreases. 
114 * Pass run length info to WCBench, causing WCBench runs to last for the given number of minutes. Note that longer runs seem to result in lower standard deviation flows/sec results.
115 * Pin ODL to a given number of processors. This is basically a thin hand-off to `wcbench.sh`. As mentioned above, pinning ODL allows it to be tested while the process is properly pegged.
116
117 #### Usage Details: stats.py
118
119 The `stats.py` script parses the output of `wcbench.sh`, which is stored in the file pointed at by the `RESULTS_FILE` variable in `wcbench.sh`. See the [WCBench Results](https://github.com/dfarrell07/cbench_regression#wcbench-results) section for more info on the results file. Both pure stats and graphs of results are supported by `stats.py`.
120
121 Any set of names for data points can be given to the `-s` flag to calculate their stats and to the `-g` flag to graph them against run numbers. All stats can be computed with `./stats.py -S`, just as all graphs can be generated with `-G`.
122
123 Examples are useful:
124
125 ```
126 # CBench flows/sec stats
127 ./stats.py -s flows
128 {'flows': {'max': 15036,
129            'mean': 8958.426,
130            'min': 4981,
131            'relstddev': 32.032,
132            'stddev': 2869.584},
133  'sample_size': 115}
134 ```
135
136 ```
137 # All stats
138 ./stats.py -S
139 {'fifteen_load': {'max': 0,
140                   'mean': 0.62,
141                   'min': 0,
142                   'relstddev': 0.0,
143                   'stddev': 0.0},
144  'five_load': {'max': 0,
145                'mean': 0.96,
146                'min': 0,
147                'relstddev': 0.0,
148                'stddev': 0.0},
149  'flows': {'max': 22384,
150            'mean': 22384.52,
151            'min': 22384,
152            'relstddev': 0.0,
153            'stddev': 0.0},
154  'iowait': {'max': 0, 'mean': 0.0, 'min': 0, 'relstddev': 0.0, 'stddev': 0.0},
155  'one_load': {'max': 0,
156               'mean': 0.85,
157               'min': 0,
158               'relstddev': 0.0,
159               'stddev': 0.0},
160  'runtime': {'max': 120,
161              'mean': 120.0,
162              'min': 120,
163              'relstddev': 0.0,
164              'stddev': 0.0},
165  'sample_size': 1,
166  'steal_time': {'max': 0,
167                 'mean': 0.0,
168                 'min': 0,
169                 'relstddev': 0.0,
170                 'stddev': 0.0},
171  'used_ram': {'max': 3657,
172               'mean': 3657.0,
173               'min': 3657,
174               'relstddev': 0.0,
175               'stddev': 0.0}}
176 ```
177
178 ```
179 # Create graphs of flows/sec and used RAM stats
180 ./stats.py -g flows ram
181 ```
182
183 Graph results:
184
185 ![Graphs of flows/sec and used RAM against run number](https://cloud.githubusercontent.com/assets/880273/3562723/5b854538-0a02-11e4-8fb1-dd1544d20ae6.png)
186
187
188 ### WCBench Results
189
190 Results from `wcbench.sh` are stored in the file pointed at by the `RESULTS_FILE` variable in `wcbench.sh`. That variable defaults to `RESULTS_FILE=$BASE_DIR/"results.csv"`, which in turn resolves to `~/results.csv` by default. As you can guess from the file name, results are stored in CSV format. Note that this format was chosen because it's what's consumed by the Jenkins Plot Plugin, which ODL uses to [automatically run a subset of the functionality provided by WCBench against ODL builds](https://jenkins.opendaylight.org/integration/job/integration-master-performance-plugin/plot/).
191
192 Note that manually modifying the results file (adding/deleting lines) will cause incorrect run number values.
193
194 The data collected by WCBench and stored in the results file for each run includes:
195 * A run number for each run, starting at 0 and counting up
196 * The flows/sec average from the CBench run
197 * Unix time in seconds at the beginning of the run
198 * Unix time in seconds at the end of the run
199 * The IP address of the controller
200 * Human-readable time that the run finished
201 * The number of switches simulated by CBench
202 * The number of MAC addresses used by CBench
203 * The `TESTS_PER_SWITCH` value passed to CBench
204 * The duration of each test in milliseconds
205 * The steal time on the system running ODL at the start of the test
206 * The steal time on the system running ODL at the end of the test
207 * The total RAM on the system running ODL
208 * The used RAM on the system running ODL at the end of a test run
209 * The free RAM on the system running ODL at the end of a test run
210 * The number of CPUs on the system running ODL
211 * The one minute load of the system running ODL
212 * The five minute load of the system running ODL
213 * The fifteen minute load of the system running ODL
214 * The name of the controller under test
215 * The iowait value at the start of the test on the system running ODL
216 * The iowait value at the end of the test on the system running ODL
217
218 ### Detailed Walkthrough: Vagrant
219
220 A Vagrantfile is provided for WCBench, which allows you to get an OpenDaylight+WCBench environment up-and-running trivially easily. Vagrant also allows folks on otherwise unsupported operating systems (Ubuntu, Debian, Windows) to use WCBench.
221
222 If you don't have Vagrant installed already, head over to [their docs](https://docs.vagrantup.com/v2/installation/) and get that knocked out.
223
224 If you haven't already, you'll need to clone the WCBench repo:
225
226 ```
227 [~]$ git clone https://github.com/dfarrell07/wcbench.git
228 ```
229
230 You can now trivially stand up a VM with OpenDaylight+CBench+WCBench properly configured:
231
232 ```
233 [~/wcbench]$ vagrant up
234 ```
235
236 If this is your first time using the `chef/fedora-20` Vagrant box, that'll have to download. Future `vagrant up`s will use a locally cached version. Once the box is provisioned, you can connect to it like this:
237
238 ```
239 [~/wcbench]$ vagrant ssh
240 Last login: Mon Nov 17 14:29:33 2014 from 10.0.2.2
241 [vagrant@localhost ~]$
242 ```
243
244 WCBench, OpenDaylight and CBench are already installed and configured. You can start OpenDaylight like this:
245
246 ```
247 [vagrant@localhost ~]$ cd wcbench/
248 [vagrant@localhost wcbench]$ ./wcbench.sh -o
249 Starting OpenDaylight
250 Will repeatedly attempt connecting to Karaf shell until it's ready
251 Issued `dropAllPacketsRpc on` command via Karaf shell to localhost:8101
252 Issued `log:set ERROR` command via Karaf shell to localhost:8101
253 ```
254
255 Run CBench against OpenDaylight like this:
256
257 ```
258 [vagrant@localhost wcbench]$ ./wcbench.sh -r
259 Collecting pre-test stats
260 Running CBench against ODL on localhost:6633
261 Collecting post-test stats
262 Collecting time-irrelevant stats
263 Average responses/second: 29486.95
264 ```
265
266 Since the WCBench Vagrant box is headless, you'll want to move the `results.txt` to a system with a GUI for graphing.
267
268 Vagrant hard-links `/home/vagrant/wcbench/` to the directory on your local system that contains WCBench's Vagrantfile. Dropping `results.txt` in `/home/vagrant/wcbench/` will therefore move it to your local system for analysis. You can also modify the `RESULTS_FILE` variable in `wcbench.sh` to point at `/home/vagrant/wcbench/`, if you'd like to put it there by default.
269
270 ```
271 # Move results.txt to hard-linked dir
272 [vagrant@localhost wcbench]$ mv ../results.csv .
273 ```
274
275 ```
276 # Configure wcbench to create results.txt in hard-linked dir
277 RESULTS_FILE=$BASE_DIR/wcbench/"results.csv"
278 ```
279
280 You can now generate graphs and stats, as described in the [Usage Details: stats.py](#user-content-usage-details-statspy) section.
281
282 To run long batches of tests, use `loop_wcbench.sh`, as described in [Usage Details: loop_wcbench.sh](#user-content-usage-details-loop_wcbenchsh).
283
284 Once you're done, you can kill OpenDaylight like this:
285
286 ```
287 [vagrant@localhost wcbench]$ ./wcbench.sh -k
288 Stopping OpenDaylight
289 ```
290
291 Unless you want a fresh WCBench Vagrant box, you can save yourself some time at your next `vagrant up` by suspending (instead of destroying) the box:
292
293 ```
294 # On my local system
295 [~/wcbench]$ vagrant suspend
296 ==> default: Saving VM state and suspending execution...
297 ```
298
299 ### Detailed Walkthrough: Manual
300
301 This walkthrough describes how to setup a system for WCBench testing, starting with a totally fresh [Fedora 20 Cloud](http://fedoraproject.org/get-fedora#clouds) install. I'm going to leave out the VM creation details for the sake of space. As long as you can SSH into the machine and it has access to the Internet, all of the following should work as-is. Note that this process has also been tested on CentOS 6.5 (so obviously should work on RHEL).
302
303 I suggest starting by adding the WCBench VM to your `~/.ssh/config` file, to allow quick access without having to remember details.
304
305 ```
306 [~]$ vim .ssh/config
307 ```
308
309 Add something like the following:
310
311 ```
312 Host wcbench
313     Hostname 10.3.9.110
314     User fedora
315     IdentityFile /home/daniel/.ssh/id_rsa_nopass
316     StrictHostKeyChecking no
317 ```
318
319 You can now SSH into your fresh VM:
320
321 ```
322 [~]$ ssh wcbench
323 Warning: Permanently added '10.3.9.110' (RSA) to the list of known hosts.
324 [fedora@dfarrell-wcbench ~]$
325 ```
326
327 You'll need a utility like screen or tmux, so you can start long-running tests, log out of the system and leave them running. My Linux configurations are very scripted, so here's how I install tmux and its configuration file. You're welcome to copy this.
328
329 From my local system:
330
331 ```
332 [~]$ rsync ~/.dotfiles/linux_setup.sh wcbench:/home/fedora
333 ```
334
335 That `linux_setup.sh` script can be found [here](https://github.com/dfarrell07/dotfiles/blob/master/linux_setup.sh).
336
337 Back on the remote VM:
338
339 ```
340 [fedora@dfarrell-wcbench ~]$ sudo yum update -y; ./linux_setup.sh -t
341 ```
342
343 Go get some coffee, this will take a while.
344
345 Once your VM is updated and tmux is installed, drop into a tmux session.
346
347 ```
348 [fedora@dfarrell-wcbench ~]$ tmux new
349 ```
350
351 For the sake of simplicity, I'm going to do an HTTPS clone of the WCBench repo. You may want to setup your SSH info on the VM and clone via SSH if you're going to be contributing (which is encouraged!).
352
353 NB: Git was installed for me during the `./linux_setup.sh -t` step, as that cloned my [.dotfiles repo](https://github.com/dfarrell07/dotfiles/). If you don't have git, install it with `sudo yum install git -y`.
354
355 ```
356 [fedora@dfarrell-wcbench ~]$ git clone https://github.com/dfarrell07/wcbench.git
357 [fedora@dfarrell-wcbench ~]$ ls -rc
358 linux_setup.sh  wcbench
359 [fedora@dfarrell-wcbench ~]$ cd wcbench/
360 ```
361
362 Huzzah! You now have WCBench "installed" on your VM. Now, to install CBench and OpenDaylight.
363
364 ```
365 [fedora@dfarrell-wcbench wcbench]$ ./wcbench.sh -ci
366 CBench is not installed
367 Installing CBench dependencies
368 Cloning CBench repo into /home/fedora/oflops
369 Cloning openflow source code into /home/fedora/openflow
370 Building oflops/configure file
371 Building CBench
372 CBench is installed
373 Successfully installed CBench
374 Installing OpenDaylight dependencies
375 Downloading OpenDaylight Helium 0.2.1
376 Unzipping OpenDaylight Helium 0.2.1
377 odl-openflowplugin-flow-services added to features installed at boot
378 odl-openflowplugin-drop-test added to features installed at boot
379 ```
380
381 Huzzah! You now have CBench and OpenDaylight installed/configured.
382
383 You're ready to get started using WCBench. You can start ODL like this:
384
385 ```
386 [fedora@dfarrell-wcbench wcbench]$ ./wcbench.sh -o
387 Starting OpenDaylight
388 Will repeatedly attempt connecting to Karaf shell until it's ready
389 Issued `dropAllPacketsRpc on` command via Karaf shell to localhost:8101
390 Issued `log:set ERROR` command via Karaf shell to localhost:8101
391 ```
392
393 Here's an example of running a two minute CBench test against OpenDaylight:
394
395 ```
396 [fedora@dfarrell-wcbench wcbench]$ ./wcbench.sh -t 2 -r
397 Set MS_PER_TEST to 120000, TESTS_PER_SWITCH to 1, CBENCH_WARMUP to 0
398 Collecting pre-test stats
399 Running CBench against ODL on localhost:6633
400 Collecting post-test stats
401 Collecting time-irrelevant stats
402 Average responses/second: 22384.52
403 /home/fedora/results.csv not found or empty, building fresh one
404 ```
405
406 I suggest copying your results.csv file back to your local system for analysis, especially if you want to generate graphs. From my local system:
407
408 ```
409 [~/wcbench]$ rsync wcbench:/home/fedora/results.csv .
410 ```
411
412 You can now generate graphs and stats, as described in the [Usage Details: stats.py](#user-content-usage-details-statspy) section.
413
414 If you'd like to collect some serious long-term data, use the `loop_wcbench.sh` script (of course, back on the VM).
415
416 ```
417 [fedora@dfarrell-wcbench wcbench]$ ./loop_wcbench.sh -t 2 -r
418 # I'm not going to let this run, you get the idea
419 ```
420
421 You can then disconnect from your tmux session with `ctrl + a + d`, or `ctrl + b + d` if you're using the standard `~/.tmux.conf`. Let this loop run for a few days, then run lots of `stats.py` commands against it to see all kinds of cool stuff.
422
423 Once you're done, you can stop ODL and clean up the CBench and ODL source/binaries.
424
425 ```
426 [fedora@dfarrell-wcbench wcbench]$ ./wcbench.sh -k
427 Stopping OpenDaylight
428 [fedora@dfarrell-wcbench wcbench]$ ./wcbench.sh -d
429 Removing /home/fedora/distribution-karaf-0.2.1-Helium-SR1
430 Removing /home/fedora/distribution-karaf-0.2.1-Helium-SR1.zip
431 Removing /home/fedora/openflow
432 Removing /home/fedora/oflops
433 Removing /usr/local/bin/cbench
434 ```
435
436 ### Contributing
437
438 Contributions are encuraged! Contributions are encuraged! Contributions are encuraged! <- I can't say this enough.
439
440 The best way to contribute code is to jump on an existing [GitHub Issue](https://github.com/dfarrell07/wcbench/issues) or raise your own, then fork the code, make your changes and submit a pull request to merge your changes back into the main codebase.
441
442 Bugs or feature requests should be raised as [Issues](https://github.com/dfarrell07/wcbench/issues).
443
444 Note that the code is Open Source under a BSD 2-clause license.
445
446 ### Contact
447
448 For feature requests, bug reports and questions please raise an [Issue](https://github.com/dfarrell07/wcbench/issues). Daniel Farrell is the primary developer of this tool. He can be contacted directly at dfarrell@redhat.com or on IRC (dfarrell07 on Freenode). **Prefer public, documented communication like Issues over direct 1-1 communication. This is an Open Source project. Keep the community in the loop.**