diff --git a/storlets/gateway/common/file_manager.py b/storlets/gateway/common/file_manager.py index 18608c4e..d9621dc6 100644 --- a/storlets/gateway/common/file_manager.py +++ b/storlets/gateway/common/file_manager.py @@ -12,9 +12,10 @@ # implied. # See the License for the specific language governing permissions and # limitations under the License. +import abc -class FileManager(object): +class FileManager(object, metaclass=abc.ABCMeta): """ This class is used to load/save files required for storlet execution from/into the storage which also stores data to be processed @@ -23,22 +24,25 @@ class FileManager(object): def __init__(self): pass + @abc.abstractmethod def get_storlet(self, name): """ Load storlet file content :param name: storlet file name """ - raise NotImplementedError() + pass + @abc.abstractmethod def get_dependency(self, name): """ Load dependency file content :param name: dependency file name """ - raise NotImplementedError() + pass + @abc.abstractmethod def put_log(self, name, fobj): """ Save storlet log file to storage @@ -46,4 +50,4 @@ class FileManager(object): :param name: log file name :param data_iter: File Object """ - raise NotImplementedError() + pass diff --git a/storlets/sbus/datagram.py b/storlets/sbus/datagram.py index 4b29f8e2..5f8206dd 100644 --- a/storlets/sbus/datagram.py +++ b/storlets/sbus/datagram.py @@ -12,6 +12,7 @@ # implied. # See the License for the specific language governing permissions and # limitations under the License. +import abc import copy import json @@ -47,14 +48,15 @@ class SBusFileDescriptor(object): return cls(fdtype, fileno, storlets_metadata, storage_metadata) -class SBusDatagram(object): +class SBusDatagram(object, metaclass=abc.ABCMeta): """ The manager class for the datagram passed over sbus protocol """ - # Each child Datagram should define what fd types are expected with - # list format - _required_fdtypes = None + @property + @abc.abstractmethod + def _required_fdtypes(self): + pass def __init__(self, command, sfds, params=None, task_id=None): """ @@ -67,9 +69,6 @@ class SBusDatagram(object): :param task_id: An optional string task id. This is currently used for cancel command """ - if type(self) == SBusDatagram: - raise NotImplementedError( - 'SBusDatagram class should not be initialized as bare') self.command = command fdtypes = [sfd.fdtype for sfd in sfds] self._check_required_fdtypes(fdtypes) @@ -145,11 +144,6 @@ class SBusDatagram(object): return ret[0] def _check_required_fdtypes(self, given_fdtypes): - if self._required_fdtypes is None: - raise NotImplementedError( - 'SBusDatagram class should define _required_fdtypes') - # the first len(self._required_fdtypes) types should be fit - # to the required list if given_fdtypes[:len(self._required_fdtypes)] != \ self._required_fdtypes: raise ValueError('Fd type mismatch given_fdtypes:%s \ @@ -178,7 +172,9 @@ class SBusServiceDatagram(SBusDatagram): - SBUS_CMD_PING - SBUS_CMD_CANCEL """ - _required_fdtypes = [sbus_fd.SBUS_FD_SERVICE_OUT] + @property + def _required_fdtypes(self): + return [sbus_fd.SBUS_FD_SERVICE_OUT] def __init__(self, command, sfds, params=None, task_id=None): super(SBusServiceDatagram, self).__init__( @@ -190,11 +186,16 @@ class SBusServiceDatagram(SBusDatagram): class SBusExecuteDatagram(SBusDatagram): - _required_fdtypes = [sbus_fd.SBUS_FD_SERVICE_OUT, - sbus_fd.SBUS_FD_INPUT_OBJECT, - sbus_fd.SBUS_FD_OUTPUT_OBJECT, - sbus_fd.SBUS_FD_OUTPUT_OBJECT_METADATA, - sbus_fd.SBUS_FD_LOGGER] + + @property + def _required_fdtypes(self): + return [ + sbus_fd.SBUS_FD_SERVICE_OUT, + sbus_fd.SBUS_FD_INPUT_OBJECT, + sbus_fd.SBUS_FD_OUTPUT_OBJECT, + sbus_fd.SBUS_FD_OUTPUT_OBJECT_METADATA, + sbus_fd.SBUS_FD_LOGGER + ] def __init__(self, command, sfds, params=None, task_id=None): # TODO(kota_): the args command is not used in ExecuteDatagram diff --git a/tests/unit/sbus/test_datagram.py b/tests/unit/sbus/test_datagram.py index fa8b083a..8a932835 100644 --- a/tests/unit/sbus/test_datagram.py +++ b/tests/unit/sbus/test_datagram.py @@ -16,7 +16,7 @@ import json import unittest import storlets.sbus.file_description as sbus_fd -from storlets.sbus.datagram import SBusFileDescriptor, SBusDatagram, \ +from storlets.sbus.datagram import SBusFileDescriptor, \ SBusServiceDatagram, SBusExecuteDatagram, build_datagram, \ build_datagram_from_raw_message from storlets.sbus.command import SBUS_CMD_PING, SBUS_CMD_EXECUTE @@ -53,27 +53,6 @@ class TestSBusFileDescriptor(unittest.TestCase): fd.storage_metadata) -class TestSBusDatagram(unittest.TestCase): - def test_check_required_fdtypes_not_implemented(self): - # SBusDatagram designed not to be called independently - with self.assertRaises(NotImplementedError) as err: - SBusDatagram('', [], []) - self.assertEqual( - 'SBusDatagram class should not be initialized as bare', - err.exception.args[0]) - - def test_invalid_child_class_definition(self): - # no definition for _required_fdtypes - class InvalidSBusDatagram(SBusDatagram): - pass - - with self.assertRaises(NotImplementedError) as err: - InvalidSBusDatagram('', [], []) - self.assertEqual( - 'SBusDatagram class should define _required_fdtypes', - err.exception.args[0]) - - class SBusDatagramTestMixin(object): def setUp(self): self.params = {'param1': 'paramvalue1'}