Feature commit #2 to support running fio

Change-Id: If08ebf50a3c59647f40a498fdfdb180b4ab5176b
This commit is contained in:
Yichen Wang 2016-01-19 16:53:11 -08:00
parent fb855864f8
commit 51dad53784
8 changed files with 97 additions and 26 deletions

View File

@ -123,15 +123,16 @@ class KB_Instance(object):
# Run fio
@staticmethod
def run_fio(dest_path, name, rw, bs, iodepth, runtime, rate_iops, rate, status_interval):
fixed_opt = '--thread --ioengine=libaio --out-format=json+ '
def run_fio(dest_path, name, mode, block_size, iodepth,
runtime, rate_iops=None, rate=None, status_interval=None):
fixed_opt = '--thread --ioengine=libaio --output-format=json+ --direct=1 '
fixed_opt += '--filename=/mnt/volume/kb_storage_test.bin '
required_opt = '--name=%s --rw=%s --bs=%s --iodepth=%s --runtime=%s ' %\
(name, rw, bs, iodepth, runtime)
(name, mode, block_size, iodepth, runtime)
optional_opt = ''
optional_opt += '--rate_iops=%s ' % rate_iops if rate_iops else ''
optional_opt += '--rate=%s ' % rate if rate else ''
optional_opt += '--status_interval=%s ' % status_interval if status_interval else ''
optional_opt += '--status-interval=%s ' % status_interval if status_interval else ''
cmd = '%s %s %s %s' % (dest_path, fixed_opt, required_opt, optional_opt)
return cmd
@ -206,7 +207,7 @@ class KBA_Client(object):
p_output = line
else:
p_output += line
if line.strip() == "}":
if line.rstrip() == "}":
cmd_res_dict = dict(zip(("status", "stdout", "stderr"), (0, p_output, '')))
continue
@ -289,7 +290,8 @@ class KBA_Storage_Client(KBA_Client):
def exec_run_storage_test(self, fio_configs):
self.last_cmd = KB_Instance.run_fio(
dest_path='usr/local/bin/fio',
dest_path='/usr/local/bin/fio',
name='kb_storage_test',
**fio_configs)
return self.exec_command_report(self.last_cmd)

View File

@ -172,7 +172,7 @@ class BaseNetwork(object):
for instance in self.instance_list:
if instance.vol:
instance.detach_vol()
bs_obj.delete_vol(instance.vol)
flag = flag & bs_obj.delete_vol(instance.vol)
instance.delete_server()
if instance.fip:
# Delete the Floating IP

View File

@ -12,6 +12,8 @@
# License for the specific language governing permissions and limitations
# under the License.
import time
import log as logging
LOG = logging.getLogger(__name__)
@ -23,14 +25,24 @@ class BaseStorage(object):
def __init__(self, cinderclient):
self.cinderclient = cinderclient
# from cinderclient.v2 import client as cinderclient
# self.cinderclient = cinderclient.Client(endpoint_type='publicURL', **creden_nova)
def create_vol(self, size, name=None):
return self.cinderclient.volumes.create(size, name=name)
def delete_vol(self, volume):
self.cinderclient.volumes.force_delete(volume)
"""
Sometimes this maybe in use if volume is just deleted
Add a retry mechanism
"""
for _ in range(10):
try:
self.cinderclient.volumes.force_delete(volume)
return True
except Exception:
time.sleep(2)
LOG.error('Failed while deleting volume %s.' % volume.id)
return False
# DO NOT USE THESE TWO APIS, THEY WILL CREATE TROUBLES WHEN TRYING TO DETACH
# OR DELETE THE VOLUMES. Volume attachment should be done via NOVA not CINDER

View File

@ -181,6 +181,50 @@ client:
# Duration of testing tools (seconds)
duration: 30
# Storage tool specific configs (per VM)
# Multiple factors can impact the storage performance numbers, and KloudBuster is defining
# a default profile which consists of four testing scenarios:
# (1) Random read
# (2) Random write
# (3) Sequential read
# (4) Sequential write
#
# Accepted testing parameters for each scenario:
# mode: (Required)
# Self-explained with the name, must be one of the below:
# ['randread', 'randwrite', 'read', 'write']
# runtime: (Required)
# Test duration in seconds
# block_size: (Optional, default=4k)
# Block size for I/O units
# iodepth: (Optional, default=1)
# Number of I/O units to keep in flight against the file
# rate_iops: (Optional, default=unlimited)
# Cap the bandwidth to this number of IOPS
# rate: (Optional, default=unlimited)
# Cap the bandwidth to this number of bytes/sec, normal postfix rules apply
storage_tool_configs:
- mode: 'randread'
runtime: 30
block_size: '4k'
iodepth: 4
rate_iops: 100
- mode: 'randwrite'
runtime: 30
block_size: '4k'
iodepth: 4
rate_iops: 100
- mode: 'read'
runtime: 30
block_size: '64k'
iodepth: 64
rate: '60m'
- mode: 'write'
runtime: 30
block_size: '64k'
iodepth: 64
rate: '60m'
# Volumes size in GB for each VM, setting to 0 to disable volume creation
volume_size: 0

View File

@ -88,8 +88,13 @@ for line in $VOL_LIST; do
ins_id=`echo $vol_list | grep $line | cut -d'|' -f9 | xargs`
if [ "$ins_id" != "" ]; then
nova volume-detach $ins_id $line
while true; do
vol_st=`cinder list --all-tenants | grep $line | cut -d'|' -f4 | xargs`
if [ $? -ne 0 ]; then break; fi
if [ "$vol_st" == "available" ]; then break; fi
done
fi
cinder force-delete $line
cinder force-delete $line &
done;
for line in $INSTANCE_LIST; do

View File

@ -223,7 +223,7 @@ class KBRunner(object):
self.host_stats[phy_host] = perf_tool.consolidate_results(self.host_stats[phy_host])
@abc.abstractmethod
def run(self, http_test_only=False):
def run(self, test_only=False):
# must be implemented by sub classes
return None

View File

@ -108,8 +108,8 @@ class KBRunner_HTTP(KBRunner):
except KBHTTPBenchException:
raise KBException("Error while running HTTP benchmarking tool.")
def run(self, http_test_only=False):
if not http_test_only:
def run(self, test_only=False):
if not test_only:
# Resources are already staged, just re-run the HTTP benchmarking tool
self.wait_for_vm_up()
@ -147,11 +147,11 @@ class KBRunner_HTTP(KBRunner):
description = "-- %s --" % self.header_formatter(cur_stage, len(self.client_dict))
LOG.info(description)
self.single_run(active_range=[0, target_vm_count - 1],
http_test_only=http_test_only)
http_test_only=test_only)
LOG.info('-- Stage %s: %s --' % (cur_stage, str(self.tool_result)))
self.tool_result['description'] = description
cur_stage += 1
yield self.tool_result
else:
self.single_run(http_test_only=http_test_only)
self.single_run(http_test_only=test_only)
yield self.tool_result

View File

@ -39,12 +39,12 @@ class KBRunner_Storage(KBRunner):
if cnt_succ != len(self.client_dict):
raise KBInitVolumeException()
def run_storage_test(self, active_range):
def run_storage_test(self, active_range, tool_config):
func = {'cmd': 'run_storage_test', 'active_range': active_range,
'parameter': dict(self.config.storage_tool_configs)}
'parameter': tool_config}
self.send_cmd('EXEC', 'storage', func)
# Give additional 30 seconds for everybody to report results
timeout = self.config.storage_tool_configs.runtime + 30
timeout = tool_config['runtime'] + 30
cnt_pending = self.polling_vms(timeout)[2]
if cnt_pending != 0:
LOG.warning("Testing VMs are not returning results within grace period, "
@ -52,7 +52,7 @@ class KBRunner_Storage(KBRunner):
# Parse the results from storage benchmarking tool
for key, instance in self.client_dict.items():
self.result[key] = instance.storage_client_parser(**self.result[key])
self.result[key] = instance.perf_client_parser(**self.result[key])
def single_run(self, active_range=None, test_only=False):
try:
@ -64,12 +64,20 @@ class KBRunner_Storage(KBRunner):
print "Press enter to start running benchmarking tools..."
raw_input()
LOG.info("Running Storage Benchmarking...")
self.report = {'seq': 0, 'report': None}
self.result = {}
# self.run_storage_test(active_range)
# Call the method in corresponding tools to consolidate results
test_count = len(self.config.storage_tool_configs)
perf_tool = self.client_dict.values()[0].perf_tool
for idx, cur_config in enumerate(self.config.storage_tool_configs):
LOG.info("Runing test case %d of %d..." % (idx + 1, test_count))
self.report = {'seq': 0, 'report': None}
self.result = {}
self.run_storage_test(active_range, dict(cur_config))
# Call the method in corresponding tools to consolidate results
LOG.kbdebug(self.result.values())
self.tool_result = perf_tool.consolidate_results(self.result.values())
vm_count = active_range[1] - active_range[0] + 1\
if active_range else len(self.full_client_dict)
self.tool_result['total_client_vms'] = vm_count
self.tool_result['total_server_vms'] = self.tool_result['total_client_vms']
except KBInitVolumeException:
raise KBException("Could not initilize the volume.")