Updated WCBench tool to v1.0.
[integration/test.git] / test / 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](#user-content-detailed-walkthrough)
14     - [Contributing](#user-content-contributing)
15     - [Contact](#user-content-contact)
16
17 ### Overview
18
19 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.
20
21 WCBench currently only supports the OpenDaylight SDN controller, but it would be fairly easy to add support for other controllers. Community contributions are encouraged!
22
23 ### Usage
24
25 #### Usage Overview
26
27 The help outputs produced by `./wcbench.sh -h`, `./loop_wcbench.sh -h` and `stats.py -h` are quite useful:
28
29 ```
30 Usage ./wcbench.sh [options]
31
32 Setup and/or run CBench and/or OpenDaylight.
33
34 OPTIONS:
35     -h Show this message
36     -c Install CBench
37     -t <time> Run CBench for given number of minutes
38     -r Run CBench against OpenDaylight
39     -i Install ODL from last successful build
40     -p <processors> Pin ODL to given number of processors
41     -o Run ODL from last successful build
42     -k Kill OpenDaylight
43     -d Delete local ODL and CBench code
44 ```
45
46 ```
47 Usage ./loop_wcbench.sh [options]
48
49 Run WCBench against OpenDaylight in a loop.
50
51 OPTIONS:
52     -h Show this help message
53     -l Loop WCBench runs without restarting ODL
54     -r Loop WCBench runs, restart ODL between runs
55     -t <time> Run WCBench for a given number of minutes
56     -p <processors> Pin ODL to given number of processors
57 ```
58
59 ```
60 usage: stats.py [-h] [-S]
61                 [-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} ...]]
62                 [-G]
63                 [-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} ...]]
64
65 Compute stats about CBench data
66
67 optional arguments:
68   -h, --help            show this help message and exit
69   -S, --all-stats       compute all stats
70   -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} ...]
71                         compute stats on specified data
72   -G, --all-graphs      graph all data
73   -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} ...]
74                         graph specified data
75 ```
76
77 #### Usage Details: wcbench.sh
78
79 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.
80
81 In more detail, the `wcbench.sh` script supports:
82
83 * Trivially cloning, building and installing CBench via the [oflops repo](https://github.com/andi-bigswitch/oflops).
84 * 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.
85 * 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`:
86
87 ```
88 Host cbench
89     Hostname 209.132.178.170
90     User fedora
91     IdentityFile /home/daniel/.ssh/id_rsa_nopass
92     StrictHostKeyChecking no
93 ```
94
95 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.
96 * Trivially installing/configuring ODL from the last successful build (via an Integration team Jenkins job).
97 * 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.
98 * Running OpenDaylight and issuing all of the required configurations. Note that the `ODL_STARTUP_DELAY` variable in `wcbench.sh` might need some attention when running on a new system. If ODL takes longer than this value (in seconds) to start, `wcbench.sh` will attempt to issue the required configuration via telnet to the OSGi console before ODL can accept the configuration changes. This will result in fairly obvious error messages dumped to stdout. If you see these, increase the `ODL_STARTUP_DELAY` time. Alternatively, you can manually issue the required configuration after ODL starts by connecting to the OSGi console via telnet and issuing `dropAllPacketsRpc on`. See the `issue_odl_config` function in `wcbench.sh` for more info. Note that there's an open issue to make this config process more robust ([Issue #6](issue_odl_config)). Community contributions solicited!
99 * Stopping the OpenDaylight process. This is done cleanly via the `run.sh` script, not `kill` or `pkill`.
100 * Cleaning up everything changed by the `wcbench.sh` script, including deleting ODL and CBench sources and binaries.
101
102
103 #### Usage Details: loop_wcbench.sh
104
105 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.
106
107 In more detail, the `loop_wcbench.sh` script supports:
108
109 * 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).
110 * 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. 
111 * 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.
112 * 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.
113
114 #### Usage Details: stats.py
115
116 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`.
117
118 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`.
119
120 Examples are useful:
121
122 ```
123 # CBench flows/sec stats
124 ./stats.py -s flows
125 {'flows': {'max': 15036,
126            'mean': 8958.426,
127            'min': 4981,
128            'relstddev': 32.032,
129            'stddev': 2869.584},
130  'sample_size': 115}
131 ```
132
133 ```
134 # Command for graphs of flows/sec and used RAM stats
135 ./stats.py -g flows ram
136 ```
137
138 Graph results:
139
140 ![Graphs of flows/sec and used RAM against run number](https://cloud.githubusercontent.com/assets/880273/3562723/5b854538-0a02-11e4-8fb1-dd1544d20ae6.png)
141
142
143 ### WCBench Results
144
145 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/).
146
147 Note that manually modifying the results file (adding/deleting lines) will cause incorrect run number values.
148
149 The data collected by WCBench and stored in the results file for each run includes:
150 * A run number for each run, starting at 0 and counting up
151 * The flows/sec average from the CBench run
152 * Unix time in seconds at the beginning of the run
153 * Unix time in seconds at the end of the run
154 * The IP address of the controller
155 * Human-readable time that the run finished
156 * The number of switches simulated by CBench
157 * The number of MAC addresses used by CBench
158 * The `TESTS_PER_SWITCH` value passed to CBench
159 * The duration of each test in milliseconds
160 * The steal time on the system running ODL at the start of the test
161 * The steal time on the system running ODL at the end of the test
162 * The total RAM on the system running ODL
163 * The used RAM on the system running ODL at the end of a test run
164 * The free RAM on the system running ODL at the end of a test run
165 * The number of CPUs on the system running ODL
166 * The one minute load of the system running ODL
167 * The five minute load of the system running ODL
168 * The fifteen minute load of the system running ODL
169 * The name of the controller under test
170 * The iowait value at the start of the test on the system running ODL
171 * The iowait value at the end of the test on the system running ODL
172
173 ### Detailed Walkthrough
174
175 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).
176
177 I suggest starting by adding the WCBench VM to your `~/.ssh/config` file, to allow quick access without having to remember details.
178
179 ```
180 [~]$ vim .ssh/config
181 ```
182
183 Add something like the following:
184
185 ```
186 Host wcbench
187     Hostname 10.3.9.110
188     User fedora
189     IdentityFile /home/daniel/.ssh/id_rsa_nopass
190     StrictHostKeyChecking no
191 ```
192
193 You can now SSH into your fresh VM:
194
195 ```
196 [~]$ ssh wcbench
197 Warning: Permanently added '10.3.9.110' (RSA) to the list of known hosts.
198 [fedora@dfarrell-wcbench ~]$ 
199 ```
200
201 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.
202
203 From my local system:
204
205 ```
206 [~]$ rsync ~/.dotfiles/linux_setup.sh wcbench:/home/fedora
207 ```
208
209 That `linux_setup.sh` script can be found [here](https://github.com/dfarrell07/dotfiles/blob/master/linux_setup.sh).
210
211 Back on the remote VM:
212
213 ```
214 [fedora@dfarrell-wcbench ~]$ sudo yum update -y; ./linux_setup.sh -t
215 ```
216
217 Go get some coffee, this will take a while.
218
219 Once your VM is updated and tmux is installed, drop into a tmux session.
220
221 ```
222 [fedora@dfarrell-wcbench ~]$ tmux new
223 ```
224
225 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!).
226
227 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`.
228
229 ```
230 [fedora@dfarrell-wcbench ~]$ git clone https://github.com/dfarrell07/wcbench.git
231 [fedora@dfarrell-wcbench ~]$ ls -rc
232 linux_setup.sh  wcbench
233 [fedora@dfarrell-wcbench ~]$ cd wcbench/
234 ```
235
236 Huzzah! You now have WCBench "installed" on your VM. Now, to install CBench and OpenDaylight.
237
238 ```
239 [fedora@dfarrell-wcbench wcbench]$ ./wcbench.sh -ci
240 CBench is not installed
241 Installing CBench dependencies
242 Cloning CBench repo
243 Cloning openflow source code
244 Building oflops/configure file
245 Building CBench
246 CBench is installed
247 Successfully installed CBench
248 Installing OpenDaylight dependencies
249 Downloading last successful ODL build
250 Unzipping last successful ODL build
251 Downloading openflowplugin
252 Removing simpleforwarding plugin
253 Removing arphandler plugin
254 ```
255
256 Huzzah! You now have CBench and OpenDaylight installed/configured.
257
258 You're ready to get started using WCBench. You can start ODL like this:
259
260 ```
261 [fedora@dfarrell-wcbench wcbench]$ ./wcbench.sh -o
262 Starting OpenDaylight
263 Giving ODL 90 seconds to get up and running
264 80 seconds remaining
265 70 seconds remaining
266 60 seconds remaining
267 50 seconds remaining
268 40 seconds remaining
269 30 seconds remaining
270 20 seconds remaining
271 10 seconds remaining
272 0 seconds remaining
273 Installing telnet, as it's required for issuing ODL config.
274 Issuing `dropAllPacketsRpc on` command via telnet to localhost:2400
275 Trying ::1...
276 Connected to localhost.
277 Escape character is '^]'.
278 osgi> dropAllPacketsRpc on
279 DropAllFlows transitions to on
280 osgi> Connection closed by foreign host.
281 ```
282
283 Here's an example of running a two minute CBench test against OpenDaylight:
284
285 ```
286 [fedora@dfarrell-wcbench wcbench]$ ./wcbench.sh -t 2 -r
287 Set MS_PER_TEST to 120000, TESTS_PER_SWITCH to 1, CBENCH_WARMUP to 0
288 Collecting pre-test stats
289 Running CBench against ODL on localhost:6633
290 Collecting post-test stats
291 Collecting time-irrelevant stats
292 Average responses/second: 22384.52
293 /home/fedora/results.csv not found or empty, building fresh one
294 ```
295
296 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:
297
298 ```
299 [~/wcbench]$ rsync wcbench:/home/fedora/results.csv .
300 ```
301
302 You can now run `stats.py` against it:
303
304 ```
305 [~/wcbench]$ ./stats.py -S
306 {'fifteen_load': {'max': 0,
307                   'mean': 0.62,
308                   'min': 0,
309                   'relstddev': 0.0,
310                   'stddev': 0.0},
311  'five_load': {'max': 0,
312                'mean': 0.96,
313                'min': 0,
314                'relstddev': 0.0,
315                'stddev': 0.0},
316  'flows': {'max': 22384,
317            'mean': 22384.52,
318            'min': 22384,
319            'relstddev': 0.0,
320            'stddev': 0.0},
321  'iowait': {'max': 0, 'mean': 0.0, 'min': 0, 'relstddev': 0.0, 'stddev': 0.0},
322  'one_load': {'max': 0,
323               'mean': 0.85,
324               'min': 0,
325               'relstddev': 0.0,
326               'stddev': 0.0},
327  'runtime': {'max': 120,
328              'mean': 120.0,
329              'min': 120,
330              'relstddev': 0.0,
331              'stddev': 0.0},
332  'sample_size': 1,
333  'steal_time': {'max': 0,
334                 'mean': 0.0,
335                 'min': 0,
336                 'relstddev': 0.0,
337                 'stddev': 0.0},
338  'used_ram': {'max': 3657,
339               'mean': 3657.0,
340               'min': 3657,
341               'relstddev': 0.0,
342               'stddev': 0.0}}
343 ```
344
345 If you'd like to collect some serious long-term data, use the `loop_wcbench.sh` script (of course, back on the VM).
346
347 ```
348 [fedora@dfarrell-wcbench wcbench]$ ./loop_wcbench.sh -t 2 -r
349 # I'm not going to let this run, you get the idea
350 ```
351
352 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.
353
354 Once you're done, you can stop ODL and clean up the CBench and ODL source/binaries.
355
356 ```
357 [fedora@dfarrell-wcbench wcbench]$ ./wcbench.sh -k
358 Stopping OpenDaylight
359 [fedora@dfarrell-wcbench wcbench]$ ./wcbench.sh -d
360 Removing /home/fedora/opendaylight
361 Removing /home/fedora/distributions-base-0.2.0-SNAPSHOT-osgipackage.zip
362 Removing /home/fedora/openflow
363 Removing /home/fedora/oflops
364 Removing /usr/local/bin/cbench
365 ```
366
367 ### Contributing
368
369 Contributions are encuraged! Contributions are encuraged! Contributions are encuraged! <- I can't say this enough.
370
371 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.
372
373 Bugs or feature requests should be raised as [Issues](https://github.com/dfarrell07/wcbench/issues).
374
375 Note that the code is Open Source under a BSD 2-clause license.
376
377 ### Contact
378
379 As mentioned in the [Contributing section](https://github.com/dfarrell07/wcbench/blob/master/README.md#contributing), for bugs/features, please raise an [Issue](https://github.com/dfarrell07/wcbench/issues) on the WCBench GitHub page.
380
381 Daniel Farrell is the main developer of WCBench. You can contact him directly at dfarrell@redhat.com or dfarrell07@gmail.com. He also hangs out on IRC at Freenode/#opendaylight most of his waking hours.