def test_list_resources(self, mock_volume_list): plugin = VolumeProtectablePlugin(self._context) mock_volume_list.return_value = \ [vol_info('123', [], 'name123'), vol_info('456', [], 'name456')] self.assertEqual([ Resource('OS::Cinder::Volume', '123', 'name123'), Resource('OS::Cinder::Volume', '456', 'name456') ], plugin.list_resources(self._context))
def test_get_server_dependent_resources(self, mock_volume_list): plugin = VolumeProtectablePlugin(self._context) attached = [{'server_id': 'abcdef', 'name': 'name'}] mock_volume_list.return_value = [ vol_info('123', attached, 'name123'), vol_info('456', [], 'name456'), ] self.assertEqual([Resource('OS::Cinder::Volume', '123', 'name123')], plugin.get_dependent_resources( self._context, Resource("OS::Nova::Server", 'abcdef', 'name')))
def test_get_dependent_resources(self, mock_server_list): plugin = ServerProtectablePlugin(self._context) server_info = collections.namedtuple('server_info', ['id', 'name']) mock_server_list.return_value = [ server_info(id='123', name='name123'), server_info(id='456', name='name456') ] self.assertEqual([ Resource('OS::Nova::Server', '123', 'name123'), Resource('OS::Nova::Server', '456', 'name456') ], plugin.get_dependent_resources(self._context, None))
def test_list_protectable_instances(self, mocker): mocker.return_value = [Resource(type='OS::Nova::Server', id='123456', name='name123'), Resource(type='OS::Nova::Server', id='654321', name='name654')] fake_cntx = mock.MagicMock() result = self.pro_manager.list_protectable_instances( fake_cntx, 'OS::Nova::Server') self.assertEqual([{'id': '123456', 'name': 'name123'}, {'id': '654321', 'name': 'name654'}], result)
def list_protectable_dependents(self, context, protectable_id, protectable_type): LOG.info( _LI("Start to list dependents of resource " "(type:%(type)s, id:%(id)s)"), { 'type': protectable_type, 'id': protectable_id }) parent_resource = Resource(type=protectable_type, id=protectable_id, name="") try: dependent_resources = \ self.protectable_registry.fetch_dependent_resources( context, parent_resource) except exception.ListProtectableResourceFailed as err: LOG.error( _LE("List dependent resources of (%(res)s) " "failed: %(err)s"), { 'res': parent_resource, 'err': six.text_type(err) }) raise result = [] for resource in dependent_resources: result.append( dict(type=resource.type, id=resource.id, name=resource.name)) return result
def test_show_resource(self, mock_volume_get): plugin = VolumeProtectablePlugin(self._context) vol_info = namedtuple('vol_info', ['id', 'name']) mock_volume_get.return_value = \ vol_info(id='123', name='name123') self.assertEqual(Resource('OS::Cinder::Volume', '123', 'name123'), plugin.show_resource(self._context, "123"))
def test_show_resource(self, mock_server_get): plugin = ServerProtectablePlugin(self._context) server_info = collections.namedtuple('server_info', ['id', 'name']) mock_server_get.return_value = \ server_info(id='123', name='name123') self.assertEqual(Resource('OS::Nova::Server', '123', 'name123'), plugin.show_resource(self._context, '123'))
def deserialize_resource_graph(serialized_resource_graph): deserialized_graph = json.loads(serialized_resource_graph) packed_resource_graph = PackedGraph(nodes=deserialized_graph[0], adjacency=deserialized_graph[1]) for sid, node in packed_resource_graph.nodes.items(): packed_resource_graph.nodes[sid] = Resource(type=node[0], id=node[1], name=node[2]) resource_graph = unpack_graph(packed_resource_graph) return resource_graph
def test_show_protectable_instance(self, mocker): mocker.return_value = Resource(type='OS::Nova::Server', id='123456', name='name123') fake_cntx = mock.MagicMock() result = self.pro_manager.show_protectable_instance( fake_cntx, 'OS::Nova::Server', '123456') self.assertEqual( {'id': '123456', 'name': 'name123', 'type': 'OS::Nova::Server'}, result)
def test_delete_backup(self): resource = Resource(id="123", type=constants.IMAGE_RESOURCE_TYPE, name='fake') resource_node = ResourceNode(value=resource, child_nodes=[]) fake_bank_section.list_objects = mock.MagicMock() fake_bank_section.list_objects.return_value = ["data_1", "data_2"] fake_bank_section.delete_object = mock.MagicMock() self.plugin.delete_backup(self.cntxt, self.checkpoint, node=resource_node)
def test_graph_building(self): A = Resource(_FAKE_TYPE, "A", 'nameA') B = Resource(_FAKE_TYPE, "B", 'nameB') C = Resource(_FAKE_TYPE, "C", 'nameC') test_matrix = ( ({ A: [B], B: [C], C: [] }, (A, C)), ({ A: [C], B: [C], C: [] }, (A, C)), ) for g, resources in test_matrix: self._fake_plugin.graph = g result_graph = self.protectable_registry.build_graph( None, resources) self.assert_graph(result_graph, g) self.protectable_registry._protectable_map = {}
def test_get_project_dependent_resources(self, mock_volume_list): project = project_info('abcd', constants.PROJECT_RESOURCE_TYPE, 'nameabcd') plugin = VolumeProtectablePlugin(self._context) volumes = [ mock.Mock(name='Volume', id='123'), mock.Mock(name='Volume', id='456'), ] setattr(volumes[0], 'os-vol-tenant-attr:tenant_id', 'abcd') setattr(volumes[1], 'os-vol-tenant-attr:tenant_id', 'efgh') setattr(volumes[0], 'name', 'name123') setattr(volumes[1], 'name', 'name456') mock_volume_list.return_value = volumes self.assertEqual( plugin.get_dependent_resources(self._context, project), [Resource('OS::Cinder::Volume', '123', 'name123')])
def test_create_backup(self): resource = Resource(id="123", type=constants.VOLUME_RESOURCE_TYPE, name="test") resource_node = ResourceNode(value=resource, child_nodes=[]) fake_bank_section.create_object = mock.MagicMock() self.plugin._cinder_client = mock.MagicMock() self.plugin._cinder_client.return_value = self.cinder_client self.cinder_client.backups.create = mock.MagicMock() self.cinder_client.backups.return_value = "456" fake_bank_section.create_object = mock.MagicMock() # fake_bank_section.update_object = mock.MagicMock() self.plugin.create_backup(self.cntxt, self.checkpoint, node=resource_node)
def test_delete_backup(self): resource = Resource(id="123", type=constants.SERVER_RESOURCE_TYPE, name="test") resource_node = ResourceNode(value=resource, child_nodes=[]) fake_bank_section.update_object = mock.MagicMock() fake_bank_section.get_object = mock.MagicMock() fake_bank_section.get_object.return_value = { "backup_id": "456" } self.plugin._cinder_client = mock.MagicMock() self.plugin._cinder_client.return_value = self.cinder_client self.cinder_client.backups.delete = mock.MagicMock() fake_bank_section.delete_object = mock.MagicMock() self.plugin.delete_backup(self.cntxt, self.checkpoint, node=resource_node)
def test_restore_backup(self): heat_template = HeatTemplate() resource = Resource(id="123", type=constants.VOLUME_RESOURCE_TYPE, name="fake") resource_node = ResourceNode(value=resource, child_nodes=[]) resource_definition = {"backup_id": "456"} kwargs = {"node": resource_node, "heat_template": heat_template, "restore_name": "smaug restore volume", "restore_description": "smaug restore"} fake_bank_section.get_object = mock.MagicMock() fake_bank_section.get_object.return_value = resource_definition self.plugin.restore_backup(self.cntxt, self.checkpoint, **kwargs) self.assertEqual(1, len(heat_template._resources)) heat_resource_id = heat_template._original_id_resource_map["123"] template_dict = { "heat_template_version": str(datetime.date(2015, 10, 15)), "description": "smaug restore template", "resources": { heat_resource_id: { "type": "OS::Cinder::Volume", "properties": { "description": "smaug restore", "backup_id": "456", "name": "smaug restore volume", } } } } self.assertEqual(template_dict, heat_template.to_dict())
def test_create_backup(self): resource = Resource(id="123", type=constants.IMAGE_RESOURCE_TYPE, name='fake') resource_node = ResourceNode(value=resource, child_nodes=[]) fake_bank_section.create_object = mock.MagicMock() self.plugin._glance_client = mock.MagicMock() self.plugin._glance_client.return_value = self.glance_client self.glance_client.images.get = mock.MagicMock() self.glance_client.images.return_value = Image(disk_format="", container_format="", status="active") fake_bank_section.update_object = mock.MagicMock() self.glance_client.images.data = mock.MagicMock() self.glance_client.images.data.return_value = "image-data" self.plugin.create_backup(self.cntxt, self.checkpoint, node=resource_node)
def build_task_flow(self, ctx): cntxt = ctx["context"] workflow_engine = ctx["workflow_engine"] operation = ctx["operation_type"] resource_context = None resource_graph = None if operation == constants.OPERATION_PROTECT: plan = ctx["plan"] task_flow = workflow_engine.build_flow(flow_name=plan.get('id')) resources = plan.get('resources') parameters = plan.get('parameters') graph_resources = [] for resource in resources: graph_resources.append(Resource(type=resource['type'], id=resource['id'], name=resource['name'])) # TODO(luobin): pass registry in ctx registry = ProtectableRegistry() registry.load_plugins() resource_graph = registry.build_graph(cntxt, graph_resources) resource_context = ResourceGraphContext( cntxt=cntxt, operation=operation, workflow_engine=workflow_engine, task_flow=task_flow, plugin_map=self._plugin_map, parameters=parameters ) if operation == constants.OPERATION_RESTORE: restore = ctx['restore'] task_flow = workflow_engine.build_flow( flow_name=restore.get('id')) checkpoint = ctx["checkpoint"] resource_graph = checkpoint.resource_graph parameters = restore.get('parameters') heat_template = ctx["heat_template"] resource_context = ResourceGraphContext( cntxt=cntxt, checkpoint=checkpoint, operation=operation, workflow_engine=workflow_engine, task_flow=task_flow, plugin_map=self._plugin_map, parameters=parameters, heat_template=heat_template ) # TODO(luobin): for other type operations walker_listener = ResourceGraphWalkerListener(resource_context) graph_walker = GraphWalker() graph_walker.register_listener(walker_listener) graph_walker.walk_graph(resource_graph) if operation == constants.OPERATION_PROTECT: return {"task_flow": walker_listener.context.task_flow, "status_getters": walker_listener.context.status_getters, "resource_graph": resource_graph} if operation == constants.OPERATION_RESTORE: return {"task_flow": walker_listener.context.task_flow}
from oslo_log import log as logging from smaug.i18n import _LE from smaug.resource import Resource from smaug.services.protection.bank_plugin import Bank from smaug.services.protection.bank_plugin import BankPlugin from smaug.services.protection.bank_plugin import BankSection from smaug.services.protection.graph import build_graph from taskflow import engines from taskflow.patterns import graph_flow from taskflow.patterns import linear_flow LOG = logging.getLogger(__name__) A = Resource(id='A', type='fake', name='fake') B = Resource(id='B', type='fake', name='fake') C = Resource(id='C', type='fake', name='fake') D = Resource(id='D', type='fake', name='fake') E = Resource(id='E', type='fake', name='fake') resource_map = { A: [C], B: [C], C: [D, E], D: [], E: [], } resource_graph = build_graph([A, B, C, D], resource_map.__getitem__)
# 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. from smaug.resource import Resource from smaug.services.protection import bank_plugin from smaug.services.protection import checkpoint from smaug.services.protection import graph from smaug.tests import base from smaug.tests.unit.protection.fakes import fake_protection_plan from smaug.tests.unit.protection.test_bank import _InMemoryBankPlugin from smaug.tests.unit.protection.test_bank import _InMemoryLeasePlugin A = Resource(id="A", type="fake", name="fake") B = Resource(id="B", type="fake", name="fake") C = Resource(id="C", type="fake", name="fake") D = Resource(id="D", type="fake", name="fake") E = Resource(id="E", type="fake", name="fake") resource_map = { A: [C], B: [C], C: [D, E], D: [], E: [], } class CheckpointTest(base.TestCase):