Modify file-exporter plugin and base TaskExporter

- Since we supports plugin bases now, lets use shorter name and rename
   "file-exporter" to just "file".
 - this patch updates the help message and docstring for connection string
   for "file-exporter"/"file" plugin
 - TaskExporter located in the task module, so it is no need to store word
   "Task" in the class name

Change-Id: Ic8a9a765e7365ff108c88a67995b9bf26736e54e
This commit is contained in:
Andrey Kurilin 2016-04-05 18:11:39 +03:00 committed by Andrey Kurilin
parent dc4be6035c
commit 5d003bfc8b
6 changed files with 37 additions and 25 deletions

View File

@ -48,12 +48,12 @@ plugins.
Proposed change Proposed change
=============== ===============
1. Implement a base class TaskExporter for an export plugin at 1. Implement a base class Exporter for an export plugin at
*rally/task/exporter.py*. *rally/task/exporter.py*.
..code-block:: python ..code-block:: python
class TaskExporter(plugin.Plugin): class Exporter(plugin.Plugin):
def export(self, task, connection_string): def export(self, task, connection_string):
... ...

View File

@ -797,7 +797,7 @@ class TaskCommands(object):
parsed_obj = urlparse.urlparse(connection_string) parsed_obj = urlparse.urlparse(connection_string)
try: try:
client = exporter.TaskExporter.get(parsed_obj.scheme)( client = exporter.Exporter.get(parsed_obj.scheme)(
connection_string) connection_string)
except exceptions.InvalidConnectionString as e: except exceptions.InvalidConnectionString as e:
if logging.is_debug(): if logging.is_debug():

View File

@ -28,14 +28,14 @@ from rally.task import exporter
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@exporter.configure(name="file-exporter") @exporter.configure(name="file")
class FileExporter(exporter.TaskExporter): class FileExporter(exporter.Exporter):
def validate(self): def validate(self):
"""Validate connection string. """Validate connection string.
The format of connection string in file plugin is The format of connection string in file plugin is
file:///<path>.<type> file:///<path>.<type-of-output>
""" """
parse_obj = urlparse.urlparse(self.connection_string) parse_obj = urlparse.urlparse(self.connection_string)
@ -44,7 +44,7 @@ class FileExporter(exporter.TaskExporter):
available_formats_str = ", ".join(available_formats) available_formats_str = ", ".join(available_formats)
if self.connection_string is None or parse_obj.path == "": if self.connection_string is None or parse_obj.path == "":
raise exceptions.InvalidConnectionString( raise exceptions.InvalidConnectionString(
"It should be `file-exporter:///<path>.<type>`.") "It should be `file:///<path>.<type-of-output>`.")
if self.type not in available_formats: if self.type not in available_formats:
raise exceptions.InvalidConnectionString( raise exceptions.InvalidConnectionString(
"Type of the exported task is not available. The available " "Type of the exported task is not available. The available "
@ -92,3 +92,13 @@ class FileExporter(exporter.TaskExporter):
f.write(res) f.write(res)
LOG.debug("Task %s results was written to the %s." % ( LOG.debug("Task %s results was written to the %s." % (
uuid, self.connection_string)) uuid, self.connection_string))
@exporter.configure(name="file-exporter")
class DeprecatedFileExporter(FileExporter):
"""DEPRECATED."""
def __init__(self, connection_string):
super(DeprecatedFileExporter, self).__init__(connection_string)
import warnings
warnings.warn("'file-exporter' plugin is deprecated. Use 'file' "
"instead.")

View File

@ -32,7 +32,7 @@ def configure(name, namespace="default"):
@plugin.base() @plugin.base()
@six.add_metaclass(abc.ABCMeta) @six.add_metaclass(abc.ABCMeta)
class TaskExporter(plugin.Plugin): class Exporter(plugin.Plugin):
def __init__(self, connection_string): def __init__(self, connection_string):
self.connection_string = connection_string self.connection_string = connection_string
@ -47,3 +47,5 @@ class TaskExporter(plugin.Plugin):
@abc.abstractmethod @abc.abstractmethod
def validate(self): def validate(self):
"""Used to validate connection string.""" """Used to validate connection string."""
TaskExporter = Exporter

View File

@ -892,38 +892,38 @@ class TaskCommandsTestCase(test.TestCase):
mock_task_get.side_effect = exceptions.TaskNotFound(uuid=task_id) mock_task_get.side_effect = exceptions.TaskNotFound(uuid=task_id)
self.assertRaises(exceptions.TaskNotFound, self.task.use, task_id) self.assertRaises(exceptions.TaskNotFound, self.task.use, task_id)
@mock.patch("rally.task.exporter.TaskExporter.get") @mock.patch("rally.task.exporter.Exporter.get")
def test_export(self, mock_task_exporter_get): def test_export(self, mock_exporter_get):
mock_client = mock.Mock() mock_client = mock.Mock()
mock_exporter_class = mock.Mock(return_value=mock_client) mock_exporter_class = mock.Mock(return_value=mock_client)
mock_task_exporter_get.return_value = mock_exporter_class mock_exporter_get.return_value = mock_exporter_class
self.task.export("fake_uuid", "file-exporter:///fake_path.json") self.task.export("fake_uuid", "file:///fake_path.json")
mock_task_exporter_get.assert_called_once_with("file-exporter") mock_exporter_get.assert_called_once_with("file")
mock_client.export.assert_called_once_with("fake_uuid") mock_client.export.assert_called_once_with("fake_uuid")
@mock.patch("rally.task.exporter.TaskExporter.get") @mock.patch("rally.task.exporter.Exporter.get")
def test_export_exception(self, mock_task_exporter_get): def test_export_exception(self, mock_exporter_get):
mock_client = mock.Mock() mock_client = mock.Mock()
mock_exporter_class = mock.Mock(return_value=mock_client) mock_exporter_class = mock.Mock(return_value=mock_client)
mock_task_exporter_get.return_value = mock_exporter_class mock_exporter_get.return_value = mock_exporter_class
mock_client.export.side_effect = IOError mock_client.export.side_effect = IOError
self.task.export("fake_uuid", "file-exporter:///fake_path.json") self.task.export("fake_uuid", "file:///fake_path.json")
mock_task_exporter_get.assert_called_once_with("file-exporter") mock_exporter_get.assert_called_once_with("file")
mock_client.export.assert_called_once_with("fake_uuid") mock_client.export.assert_called_once_with("fake_uuid")
@mock.patch("rally.cli.commands.task.sys.stdout") @mock.patch("rally.cli.commands.task.sys.stdout")
@mock.patch("rally.task.exporter.TaskExporter.get") @mock.patch("rally.task.exporter.Exporter.get")
def test_export_InvalidConnectionString(self, mock_task_exporter_get, def test_export_InvalidConnectionString(self, mock_exporter_get,
mock_stdout): mock_stdout):
mock_exporter_class = mock.Mock( mock_exporter_class = mock.Mock(
side_effect=exceptions.InvalidConnectionString) side_effect=exceptions.InvalidConnectionString)
mock_task_exporter_get.return_value = mock_exporter_class mock_exporter_get.return_value = mock_exporter_class
self.task.export("fake_uuid", "file-exporter:///fake_path.json") self.task.export("fake_uuid", "file:///fake_path.json")
mock_stdout.write.assert_has_calls([ mock_stdout.write.assert_has_calls([
mock.call("The connection string is not valid: None. " mock.call("The connection string is not valid: None. "
"Please check your connection string."), "Please check your connection string."),
mock.call("\n")]) mock.call("\n")])
mock_task_exporter_get.assert_called_once_with("file-exporter") mock_exporter_get.assert_called_once_with("file")
@mock.patch("rally.cli.commands.task.plot.charts") @mock.patch("rally.cli.commands.task.plot.charts")
@mock.patch("rally.cli.commands.task.sys.stdout") @mock.patch("rally.cli.commands.task.sys.stdout")

View File

@ -17,7 +17,7 @@ from tests.unit import test
@exporter.configure(name="test-exporter") @exporter.configure(name="test-exporter")
class TestExporter(exporter.TaskExporter): class TestExporter(exporter.Exporter):
def validate(self): def validate(self):
pass pass
@ -29,7 +29,7 @@ class TestExporter(exporter.TaskExporter):
class ExporterTestCase(test.TestCase): class ExporterTestCase(test.TestCase):
def test_task_export(self): def test_task_export(self):
self.assertRaises(TypeError, exporter.TaskExporter, "fake_connection") self.assertRaises(TypeError, exporter.Exporter, "fake_connection")
def test_task_export_instantiate(self): def test_task_export_instantiate(self):
TestExporter("fake_connection") TestExporter("fake_connection")