Feature commit #2 to support running fio
Change-Id: If08ebf50a3c59647f40a498fdfdb180b4ab5176b
This commit is contained in:
parent
fb855864f8
commit
51dad53784
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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.")
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user