Merge lp:~rodsmith/checkbox/multi-iperf-targets into lp:checkbox

Proposed by Rod Smith
Status: Merged
Approved by: Jeff Lane 
Approved revision: no longer in the source branch.
Merged at revision: 4115
Proposed branch: lp:~rodsmith/checkbox/multi-iperf-targets
Merge into: lp:checkbox
Diff against target: 183 lines (+60/-40)
1 file modified
providers/plainbox-provider-checkbox/bin/network (+60/-40)
To merge this branch: bzr merge lp:~rodsmith/checkbox/multi-iperf-targets
Reviewer Review Type Date Requested Status
Jeff Lane  Approve
Daniel Manrique (community) Approve
Review via email: mp+278631@code.launchpad.net

Description of the change

Enable network test to support multiple iperf/iperf3 targets. Aside from some changes to logging output, this should work exactly the same way as before when fed a single target. When fed multiple targets via a comma-delimited list in TEST_TARGET_IPERF, the test now tries each one in turn until one succeeds or until all the potential targets fail. This change is motivated to support server environments with separate 1Gbps and 10Gbps networks.

To post a comment you must log in.
Revision history for this message
Daniel Manrique (roadmr) wrote :

Looks OK to me, thanks.

review: Approve
Revision history for this message
Jeff Lane  (bladernr) wrote :

same here

review: Approve
4115. By Rod Smith

"automatic merge of lp:~rodsmith/checkbox/multi-iperf-targets/ by tarmac [r=bladernr,roadmr][bug=][author=rodsmith]"

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'providers/plainbox-provider-checkbox/bin/network'
2--- providers/plainbox-provider-checkbox/bin/network 2015-09-11 20:57:54 +0000
3+++ providers/plainbox-provider-checkbox/bin/network 2015-11-25 18:44:30 +0000
4@@ -96,7 +96,8 @@
5 self.timeout, self.target, self.data_size)
6
7 logging.debug(cmd)
8- print("Starting iperf, this could take some time...")
9+ logging.info("Starting iperf against {}, this could take a while...".
10+ format(self.target))
11 try:
12 iperf_return = check_output(
13 shlex.split(cmd), universal_newlines=True)
14@@ -148,8 +149,8 @@
15 return 0
16 # Below is guaranteed to not throw an exception because we'll
17 # have exited above if it did.
18- logging.info("{:03.2f}% of theoretical max {} Mb/s".format(percent,
19- int(self.iface.max_speed)))
20+ logging.info("{:03.2f}% of theoretical max {} Mb/s".
21+ format(percent, int(self.iface.max_speed)))
22 if cpu:
23 logging.info("")
24 logging.info("CPU utilization: {}%".format(cpu[0]))
25@@ -158,7 +159,8 @@
26 cpu_load = 0.0
27 if percent < self.fail_threshold or \
28 cpu_load > self.cpu_load_fail_threshold:
29- logging.warn("Poor network performance detected")
30+ logging.warn("Poor network performance detected against {}".
31+ format(self.target))
32 if percent < self.fail_threshold:
33 logging.warn(" Transfer speed: {} Mb/s".
34 format(throughput))
35@@ -170,9 +172,10 @@
36 format(self.cpu_load_fail_threshold))
37 return 30
38
39- logging.debug("Passed benchmark")
40+ logging.debug("Passed benchmark against {}".format(self.target))
41 else:
42- print("Failed iperf benchmark")
43+ logging.error("Failed iperf benchmark against {}".
44+ format(self.target))
45 return 1
46
47
48@@ -344,7 +347,9 @@
49 stdout=DEVNULL, stderr=DEVNULL)
50 except CalledProcessError as excp:
51 working_interface = False
52- logging.warning("Ping failure on %s (%s)", the_interface, excp)
53+ if num_loops == 0:
54+ logging.warning("Ping failure on {} ({})".
55+ format(the_interface, excp))
56
57 if not working_interface:
58 time.sleep(5)
59@@ -353,6 +358,38 @@
60 return working_interface
61
62
63+def run_test(args, test_target):
64+ # Ensure that interface is fully up by waiting until it can
65+ # ping the test server
66+ if not can_ping(args.interface, test_target):
67+ logging.error("Can't ping test server {} on {}".format(test_target,
68+ args.interface))
69+ return 1
70+
71+ # Execute requested networking test
72+ if args.test_type.lower() == "iperf":
73+ error_number = 0
74+ iperf_benchmark = IPerfPerformanceTest(args.interface, test_target,
75+ args.fail_threshold,
76+ args.cpu_load_fail_threshold,
77+ args.iperf3)
78+ if args.datasize:
79+ iperf_benchmark.data_size = args.datasize
80+ run_num = 0
81+ while not error_number and run_num < args.num_runs:
82+ error_number = iperf_benchmark.run()
83+ run_num += 1
84+ logging.info(" Finished run number %s ".center(60, "-"), run_num)
85+ elif args.test_type.lower() == "stress":
86+ stress_benchmark = StressPerformanceTest(args.interface,
87+ test_target, args.iperf3)
88+ error_number = stress_benchmark.run()
89+ else:
90+ logging.error("Unknown test type {}".format(args.test_type))
91+ return 10
92+ return error_number
93+
94+
95 def interface_test(args):
96 if not ("test_type" in vars(args)):
97 return
98@@ -362,10 +399,10 @@
99
100 if (args.test_type.lower() == "iperf" or
101 args.test_type.lower() == "stress"):
102- test_target = test_parameters["test_target_iperf"]
103+ test_targets = test_parameters["test_target_iperf"]
104
105 # Validate that we got reasonable values
106- if not test_target or "example.com" in test_target:
107+ if not test_targets or "example.com" in test_targets:
108 # Default values found in config file
109 logging.error("Target server has not been supplied.")
110 logging.info("Configuration settings can be configured 3 different ways:")
111@@ -393,7 +430,7 @@
112 except CalledProcessError as route_error:
113 logging.warning("Unable to save routing table: %s", route_error)
114
115- result = 0
116+ error_number = 0
117 # Stop all other interfaces
118 extra_interfaces = \
119 [iface for iface in os.listdir("/sys/class/net")
120@@ -406,34 +443,17 @@
121 except CalledProcessError as interface_failure:
122 logging.error("Failed to shut down %s:%s",
123 iface, interface_failure)
124- result = 3
125-
126- if result == 0:
127- # Ensure that interface is fully up by waiting until it can
128- # ping the test server
129- if not can_ping(args.interface, test_target):
130- logging.error("Can't ping test server on %s", args.interface)
131- return 1
132-
133- # Execute requested networking test
134- if args.test_type.lower() == "iperf":
135- iperf_benchmark = IPerfPerformanceTest(args.interface, test_target,
136- args.fail_threshold,
137- args.cpu_load_fail_threshold,
138- args.iperf3)
139- if args.datasize:
140- iperf_benchmark.data_size = args.datasize
141- run_num = 0
142- while not result and run_num < args.num_runs:
143- result = iperf_benchmark.run()
144- run_num += 1
145- logging.info(" Finished run number %s ".center(60, "-"),
146- run_num)
147-
148- elif args.test_type.lower() == "stress":
149- stress_benchmark = StressPerformanceTest(args.interface,
150- test_target, args.iperf3)
151- result = stress_benchmark.run()
152+ error_number = 3
153+
154+ if error_number == 0:
155+ test_targets_list = test_targets.split(",")
156+ test_targets_list.reverse()
157+ # Keep testing until a success or we run out of targets
158+ while test_targets_list:
159+ test_target = test_targets_list.pop().strip()
160+ error_number = run_test(args, test_target)
161+ if not error_number:
162+ break
163
164 for iface in extra_interfaces:
165 logging.debug("Restoring interface:%s", iface)
166@@ -441,7 +461,7 @@
167 check_call(["ip", "link", "set", "dev", iface, "up"])
168 except CalledProcessError as interface_failure:
169 logging.error("Failed to restore %s:%s", iface, interface_failure)
170- result = 3
171+ error_number = 3
172
173 # Restore routing table to original state
174 temp.seek(0)
175@@ -454,7 +474,7 @@
176 logging.warning("Unable to restore routing table: %s", restore_failure)
177 temp.close()
178
179- return result
180+ return error_number
181
182
183 def interface_info(args):

Subscribers

People subscribed via source and target branches