Merge lp:~bladernr/opencompute/add-iperf-test into lp:opencompute/checkbox

Proposed by Jeff Lane 
Status: Merged
Approved by: Jeff Marcom
Approved revision: 2167
Merged at revision: 2167
Proposed branch: lp:~bladernr/opencompute/add-iperf-test
Merge into: lp:opencompute/checkbox
Diff against target: 301 lines (+130/-47)
4 files modified
debian/changelog (+1/-0)
examples/network.cfg (+4/-2)
jobs/networking.txt.in (+1/-1)
scripts/network (+124/-44)
To merge this branch: bzr merge lp:~bladernr/opencompute/add-iperf-test
Reviewer Review Type Date Requested Status
Jeff Marcom (community) Approve
Review via email: mp+190721@code.launchpad.net

Commit message

Cherry pick of the iperf test additions to the multi-nic testing.

Description of the change

Cherry pick of the iperf test additions to the multi-nic testing.

To post a comment you must log in.
Revision history for this message
Jeff Marcom (jeffmarcom) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2013-10-02 21:00:13 +0000
3+++ debian/changelog 2013-10-11 16:16:45 +0000
4@@ -15,6 +15,7 @@
5 testing via stressapptest.
6 * debian/control: promoted several packages from suggest to depends to ensure
7 they are installed along with checkbox-ocp (LP: #1233333)
8+ * Cherry pick new iperf functionality in network testing from checkbox trunk
9
10 -- Jeff Marcom <jeff.marcom@canonical.com> Wed, 2 Oct 2013 10:13:04 -0400
11
12
13=== modified file 'examples/network.cfg'
14--- examples/network.cfg 2013-04-25 19:11:18 +0000
15+++ examples/network.cfg 2013-10-11 16:16:45 +0000
16@@ -1,4 +1,6 @@
17 [FTP]
18-Target: canonical.com
19+Target: your-ftp-server.example.com
20 User: anonymous
21-Pass:
22+Pass:
23+[IPERF]
24+Target: your-iperf-server.example.com
25
26=== modified file 'jobs/networking.txt.in'
27--- jobs/networking.txt.in 2013-09-08 04:14:01 +0000
28+++ jobs/networking.txt.in 2013-10-11 16:16:45 +0000
29@@ -120,7 +120,7 @@
30 package.name == 'ethtool' and package.name == 'nmap'
31 device.path == "$1"
32 user: root
33- command: network test -i $2 -t ftp
34+ command: network test -i $2 -t iperf
35 description:
36 Testing for NIC $2
37 EOF
38
39=== modified file 'scripts/network'
40--- scripts/network 2013-09-08 04:35:07 +0000
41+++ scripts/network 2013-10-11 16:16:45 +0000
42@@ -18,47 +18,102 @@
43 along with this program. If not, see <http://www.gnu.org/licenses/>.
44 """
45
46-from argparse import ArgumentParser
47+from argparse import (
48+ ArgumentParser,
49+ RawTextHelpFormatter
50+)
51 import configparser
52 import fcntl
53 import ftplib
54 from ftplib import FTP
55 import logging
56 import os
57+import re
58 import shlex
59 import socket
60 import struct
61-from subprocess import check_call, CalledProcessError
62+import subprocess
63+from subprocess import (
64+ CalledProcessError,
65+ check_call,
66+ check_output
67+)
68 import sys
69-import threading
70 import time
71
72 logging.basicConfig(level=logging.DEBUG)
73
74
75+class IPerfPerformanceTest(object):
76+ """Measures performance of interface using iperf client
77+ and target. Calculated speed is measured against theorectical
78+ throughput of selected interface"""
79+
80+ def __init__(
81+ self,
82+ interface,
83+ target,
84+ protocol="tcp",
85+ mbytes="1024M"):
86+
87+ self.iface = Interface(interface)
88+ self.target = target
89+ self.protocol = protocol
90+
91+ self.mbytes = mbytes
92+
93+ def run(self):
94+ cmd = "timeout 30 iperf -c {} -n {}".format(self.target, self.mbytes)
95+
96+ logging.debug(cmd)
97+ try:
98+ iperf_return = check_output(
99+ shlex.split(cmd), universal_newlines=True)
100+ except CalledProcessError as iperf_exception:
101+ logging.error("Failed executing iperf, Reason:", iperf_exception)
102+
103+ # 930 Mbits/sec\n'
104+ print(iperf_return)
105+ match = re.search(r'\d+\sMbits', iperf_return)
106+ if match:
107+ throughput = match.group(0).split()[0]
108+
109+ percent = int(throughput) / int(self.iface.max_speed) * 100
110+ print("Transfer speed:")
111+ print("%3.2f%% of" % percent)
112+ print("theoretical max %smbs" % int(self.iface.max_speed))
113+
114+ if percent < 40:
115+ logging.warn("Poor network performance detected")
116+ return 30
117+
118+ logging.debug("Passed benchmark")
119+ else:
120+ print("Failed iperf benchmark")
121+ return 1
122+
123+
124 class FTPPerformanceTest(object):
125- """
126- Provides file transfer rate based information while
127+ """Provides file transfer rate based information while
128 using the FTP protocol and sending a file (DEFAULT=1GB)
129 over the local or public network using a specified network
130- interface on the host.
131- """
132+ interface on the host."""
133
134 def __init__(
135 self,
136+ target,
137+ username,
138+ password,
139 interface,
140- target,
141- username="anonymous",
142- password="ftp"):
143+ binary_size=1,
144+ file2send="ftp_performance_test"):
145
146- self.iface = Interface(interface)
147 self.target = target
148 self.username = username
149 self.password = password
150-
151- self.binary_size = 1
152-
153- self.file2send = "ftp_performance_test"
154+ self.iface = Interface(interface)
155+ self.binary_size = binary_size
156+ self.file2send = file2send
157
158 def _make_file2send(self):
159 """
160@@ -88,7 +143,7 @@
161 try:
162 logging.debug("Sending file")
163 self.remote.storbinary("STOR " + filename, file, 1024)
164- except ftplib.all_errors as send_failure:
165+ except (ftplib.all_errors) as send_failure:
166 logging.error("Failed to send file to %s", self.target)
167 logging.error("Reason: %s", send_failure)
168 return 0, 0
169@@ -150,6 +205,10 @@
170
171 # Connect to FTP target and send file
172 connected = self.connect()
173+
174+ if connected is False:
175+ return 3
176+
177 filesize, delay = self.send_file()
178
179 # Remove created binary
180@@ -166,9 +225,9 @@
181 # Calculate transfer rate and determine pass/fail status
182 mbs_speed = float(filesize / 131072) / float(delay)
183 percent = (mbs_speed / int(info["Speed"])) * 100
184- logging.debug("Transfer speed:")
185- logging.debug("%3.2f%% of", percent)
186- logging.debug("theoretical max %smbs", int(info["Speed"]))
187+ print("Transfer speed:")
188+ print("%3.2f%% of" % percent)
189+ print("theoretical max %smbs" % int(info["Speed"]))
190
191 if percent < 40:
192 logging.warn("Poor network performance detected")
193@@ -285,31 +344,35 @@
194 check_call(shlex.split(cmd))
195 except CalledProcessError as interface_failure:
196 logging.error("Failed to use %s:%s", cmd, interface_failure)
197- return 1
198-
199+ sys.exit(3)
200+
201+ if test_target is None:
202+ # Set FTP parameters based on config file
203+ test_target = config.get("FTP", "Target")
204+ test_user = config.get("FTP", "User")
205+ test_pass = config.get("FTP", "Pass")
206+
207+ if args.test_type.lower() == "iperf":
208+ test_target = config.get("IPERF", "Target")
209+
210+ if "example.com" in test_target:
211+ # Default values found in config file
212+ logging.error("Please supply target via: %s", config_file)
213+ sys.exit(1)
214+
215+ # Execute FTP transfer benchmarking test
216 if args.test_type.lower() == "ftp":
217- if test_target is None:
218- # Set FTP parameters based on config file
219- test_target = config.get("FTP", "Target")
220- test_user = config.get("FTP", "User")
221- test_pass = config.get("FTP", "Pass")
222-
223- if test_target == "canonical.com":
224- # Default values found in config file
225- logging.error("Please supply target via: %s", config_file)
226- sys.exit(1)
227-
228- # Being FTP benchmark for specified interface
229 ftp_benchmark = FTPPerformanceTest(
230- args.interface,
231- test_target,
232- test_user,
233- test_pass)
234+ test_target, test_user, test_pass, args.interface)
235
236 if args.filesize:
237 ftp_benchmark.binary_size = int(args.filesize)
238 sys.exit(ftp_benchmark.run())
239
240+ elif args.test_type.lower() == "iperf":
241+ iperf_benchmark = IPerfPerformanceTest(args.interface, test_target)
242+ sys.exit(iperf_benchmark.run())
243+
244
245 def interface_info(args):
246
247@@ -329,7 +392,21 @@
248
249
250 def main():
251- parser = ArgumentParser(description="Network test module")
252+
253+ intro_message = "Network module\n\nThis script provides benchmarking " \
254+ + "and information for a specified network interface.\n\n\n" \
255+ + "Example NIC information usage:\nnetwork info -i eth0 --max-speed " \
256+ + "\n\nFor running ftp benchmark test: \nnetwork test -i eth0 -t ftp " \
257+ + "--target 192.168.0.1 --username USERID --password PASSW0RD " \
258+ + "--filesize-2\n\nPlease note that this script can use configuration " \
259+ + "values supplied via a config file.\nExample config file:\n[FTP]\n" \
260+ + "Target: 192.168.1.23\nUser: FTPUser\nPass:PassW0Rd\n" \
261+ + "[IPERF]\nTarget: 192.168.1.45\n**NOTE**\nDefault config location " \
262+ + "is /etc/checkbox.d/network.cfg"
263+
264+
265+ parser = ArgumentParser(
266+ description=intro_message, formatter_class=RawTextHelpFormatter)
267 subparsers = parser.add_subparsers()
268
269 # Main cli options
270@@ -342,14 +419,17 @@
271 test_parser.add_argument(
272 '-i', '--interface', type=str, required=True)
273 test_parser.add_argument(
274- '-t', '--test_type', type=str, default="ftp",
275- help=("Choices [FTP *Default*]"))
276+ '-t', '--test_type', type=str,
277+ choices=("ftp", "iperf"), default="ftp",
278+ help=("[FTP *Default*]"))
279 test_parser.add_argument('--target', type=str)
280- test_parser.add_argument('--username', type=str)
281- test_parser.add_argument('--password', type=str)
282+ test_parser.add_argument(
283+ '--username', type=str, help=("For FTP test only"))
284+ test_parser.add_argument(
285+ '--password', type=str, help=("For FTP test only"))
286 test_parser.add_argument(
287 '--filesize', type=str,
288- help="Size (GB) of binary file to send over network")
289+ help="Size (GB) of binary file to send **Note** for FTP test only")
290 test_parser.add_argument(
291 '--config', type=str,
292 default="/etc/checkbox.d/network.cfg",
293@@ -378,7 +458,7 @@
294
295 test_parser.set_defaults(func=interface_test)
296 info_parser.set_defaults(func=interface_info)
297-
298+
299 args = parser.parse_args()
300
301 args.func(args)

Subscribers

People subscribed via source and target branches