Ceph rados benchmarking

This commit is contained in:
David Ames
2020-08-20 14:28:18 -07:00
parent cd49a5bc9f
commit 0ca011afec
2 changed files with 139 additions and 0 deletions

View File

@@ -0,0 +1,15 @@
# Copyright 2020 Canonical Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Collection of code for benchmarking ceph."""

View File

@@ -0,0 +1,124 @@
# Copyright 2020 Canonical Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Ceph Benchmark Tests."""
import logging
import re
import unittest
import zaza.model
class BenchmarkTests(unittest.TestCase):
"""Ceph Bencharmk Tests."""
@classmethod
def setUpClass(cls):
"""Run class setup for running ceph benchmark tests."""
super().setUpClass()
cls.results_match = "^[A-Z].*"
cls.pool = "zaza_benchmarks"
cls.test_results = {}
cls.time_in_secs = 30
def parse_bench_results(self, results_string):
"""Parse bench results from string.
:param results string: Output from rados bench command.
With newlines due to juju run's output.
:type results_string: string
:returns: Dictionary of results summary
:rtype: dict
"""
_results = {}
_lines = results_string.split("\n")
for _line in _lines:
_line = _line.strip()
if re.match(self.results_match, _line):
_keyvalues = _line.split(":")
try:
_results[_keyvalues[0].strip()] = _keyvalues[1].strip()
except IndexError:
# Skipping detailed output for summary details
pass
return _results
def run_rados_bench(self, action, params=None):
"""Run rados bench.
:param action: String rados bench command i.e. write, rand, seq
:type action: string
:param params: List of string extra parameters to rados bench command
:type params: List[strings]
:returns: Unit run dict result
:rtype: dict
"""
_cmd = "rados bench -p {} {} {}".format(
self.pool, self.time_in_secs, action)
if params:
_cmd += " "
_cmd += " ".join(params)
logging.info(
"Running '{}' for {} seconds ...".format(_cmd, self.time_in_secs))
_result = zaza.model.run_on_leader(
"ceph-mon", _cmd, timeout=self.time_in_secs + 60)
return _result
def test_001_create_pool(self):
"""Create ceph pool."""
_cmd = "ceph osd pool create {} 100 100".format(self.pool)
_result = zaza.model.run_on_leader(
"ceph-mon", _cmd)
if _result.get("Code") and not _result.get("Code").startswith('0'):
if "already exists" in _result.get("Stderr", ""):
logging.warning(
"Ceph osd pool {} already exits.".format(self.pool))
else:
logging.error("Ceph osd pool create failed")
raise Exception(_result.get("Stderr", ""))
def test_100_rados_bench_write(self):
"""Rados bench write test."""
_result = self.run_rados_bench("write", params=["--no-cleanup"])
self.test_results["write"] = (
self.parse_bench_results(_result.get("Stdout", "")))
def test_200_rados_bench_read_seq(self):
"""Rados bench read sequential test."""
_result = self.run_rados_bench("seq")
self.test_results["read_seq"] = (
self.parse_bench_results(_result.get("Stdout", "")))
def test_300_rados_bench_read_rand(self):
"""Rados bench read random test."""
_result = self.run_rados_bench("rand")
self.test_results["read_rand"] = (
self.parse_bench_results(_result.get("Stdout", "")))
def test_998_rados_cleanup(self):
"""Cleanup rados bench data."""
_cmd = "rados -p {} cleanup".format(self.pool)
_result = zaza.model.run_on_leader("ceph-mon", _cmd)
if _result.get("Code") and not _result.get("Code").startswith('0'):
logging.warning("rados cleanup failed")
def test_999_print_rados_bench_results(self):
"""Print rados bench results."""
print("######## Begin Ceph Results ########")
for test, results in self.test_results.items():
print("##### {} ######".format(test))
for key, value in results.items():
print("{}: {}".format(key, value))
print("######## End Ceph Results ########")