class VirtualMachineManagerTest(unittest.TestCase):
    def setUp(self):
        def get_vn_id(obj_type, fq_name):
            if obj_type != 'virtual-network':
                return
            for vn in VirtualNetworkSM.values():
                if vn.fq_name == fq_name:
                    return vn.uuid
            raise NoIdError(fq_name)

        def vn_create(vn_obj):
            vn_obj.uuid = (':').join(vn_obj.fq_name)
            vn = {}
            vn['uuid'] = vn_obj.uuid
            vn['fq_name'] = vn_obj.fq_name
            VirtualNetworkSM.locate(vn_obj.uuid, vn)
            return

        def vmi_create(vmi_obj):
            vmi_obj.uuid = 'fake-vmi-uuid'
            return

        self.mocked_vnc = mock.MagicMock()
        self.mocked_vnc.fq_name_to_id = get_vn_id
        self.mocked_vnc.virtual_network_create = vn_create
        self.mocked_vnc.virtual_machine_interface_create = vmi_create

        self.nova_mock = mock.MagicMock()
        self.mocked_db = mock.MagicMock()

        self.mocked_args = mock.MagicMock()
        self.mocked_args.availability_zone = None

        self.vm_manager = VirtualMachineManager(
            db=self.mocked_db, logger=mock.MagicMock(),
            vnc_lib=self.mocked_vnc, vrouter_scheduler=mock.MagicMock(),
            nova_client=self.nova_mock, args=self.mocked_args)

    def tearDown(self):
        pass

    def create_test_project(self, fq_name_str):
        proj_obj = {}
        proj_obj['fq_name'] = fq_name_str.split(':')
        proj_obj['uuid'] = fq_name_str
        proj_obj['id_perms'] = 'fake-id-perms'
        ProjectSM.locate(proj_obj['uuid'], proj_obj)

    def create_test_virtual_network(self, fq_name_str):
        vn_obj = {}
        vn_obj['fq_name'] = fq_name_str.split(':')
        vn_obj['uuid'] = fq_name_str
        vn_obj['id_perms'] = 'fake-id-perms'
        VirtualNetworkSM.locate(vn_obj['uuid'], vn_obj)

    def create_test_virtual_machine(self, fq_name_str):
        vm_obj = {}
        vm_obj['fq_name'] = fq_name_str.split(':')
        vm_obj['uuid'] = fq_name_str
        vm_obj['display_name'] = fq_name_str
        vm = VirtualMachineSM.locate(vm_obj['uuid'], vm_obj)
        vm.proj_fq_name = ['fake-domain', 'fake-project']
        return vm

    def test_create(self):
        self.create_test_project('fake-domain:fake-project')
        self.create_test_virtual_network('fake-domain:fake-project:left-vn')
        self.create_test_virtual_network('fake-domain:fake-project:right-vn')

        st_obj = {}
        st_obj['fq_name'] = ['fake-domain', 'fake-template']
        st_obj['uuid'] = 'fake-st-uuid'
        st_obj['id_perms'] = 'fake-id-perms'
        st_props = {}
        st_props['flavor'] = 'm1.medium'
        st_props['image'] = 'nat-image'
        st_props['service_virtualization_type'] = 'virtual-machine'
        st_props['service_type'] = 'firewall'
        st_props['ordered_interfaces'] = True
        st_props['interface_type'] = [{'service_interface_type': 'management', 'shared_ip': False},
                                      {'service_interface_type': 'left', 'shared_ip': False},
                                      {'service_interface_type': 'right', 'shared_ip': False}]
        st_obj['service_template_properties'] = st_props

        si_obj = {}
        si_obj['fq_name'] = ['fake-domain', 'fake-project', 'fake-instance']
        si_obj['uuid'] = 'fake-si-uuid'
        si_obj['id_perms'] = 'fake-id-perms'
        si_props = {}
        si_props['scale_out'] = {'max_instances': 2}
        si_props['interface_list'] = [{'virtual_network': None},
                                      {'virtual_network': 'fake-domain:fake-project:left-vn'},
                                      {'virtual_network': 'fake-domain:fake-project:right-vn'}]
        si_obj['service_instance_properties'] = si_props

        st = ServiceTemplateSM.locate('fake-st-uuid', st_obj)
        si = ServiceInstanceSM.locate('fake-si-uuid', si_obj)

        def nova_oper(resource, oper, proj_name, **kwargs):
            if resource == 'servers' and oper == 'create':
                nova_vm = FakeNovaServer(kwargs['name'])
                return nova_vm
            else:
                return mock.MagicMock()
        self.nova_mock.oper = nova_oper

        self.vm_manager.create_service(st, si)
        vm_obj = VirtualMachine()
        self.mocked_vnc.virtual_machine_create.assert_any_call(VMObjMatcher(1))
        self.mocked_vnc.virtual_machine_create.assert_any_call(VMObjMatcher(2))

    def test_delete(self):
        vm = self.create_test_virtual_machine('fake-vm-uuid')
        self.vm_manager.delete_service(vm)
class VirtualMachineManagerTest(unittest.TestCase):
    def setUp(self):
        VirtualMachineSM._cassandra = mock.MagicMock()
        VirtualMachineSM._cassandra.object_read = test_utils.vm_db_read
        VirtualMachineInterfaceSM._cassandra = mock.MagicMock()
        VirtualMachineInterfaceSM._cassandra.object_read = test_utils.vmi_db_read
        InstanceIpSM._cassandra = mock.MagicMock()
        InstanceIpSM._cassandra.object_read = test_utils.iip_db_read
        InterfaceRouteTableSM._cassandra = mock.MagicMock()
        InterfaceRouteTableSM._cassandra.object_read = test_utils.irt_db_read
        self.mocked_vnc = mock.MagicMock()
        self.mocked_vnc.fq_name_to_id = test_utils.get_vn_id_for_fq_name
        self.mocked_vnc.virtual_network_create = test_utils.vn_create
        self.mocked_vnc.virtual_machine_interface_create = test_utils.vmi_create
        self.mocked_vnc.instance_ip_create = test_utils.iip_create

        self.nova_mock = mock.MagicMock()
        self.mocked_db = mock.MagicMock()

        self.mocked_args = mock.MagicMock()
        self.mocked_args.availability_zone = 'default-availability-zone'

        self.log_mock = mock.MagicMock()

        self.vm_manager = VirtualMachineManager(
            db=self.mocked_db,
            logger=self.log_mock,
            vnc_lib=self.mocked_vnc,
            vrouter_scheduler=mock.MagicMock(),
            nova_client=self.nova_mock,
            args=self.mocked_args,
            agent_manager=mock.MagicMock())

    def tearDown(self):
        ServiceTemplateSM.reset()
        ServiceInstanceSM.reset()
        InstanceIpSM.reset()
        VirtualMachineInterfaceSM.reset()
        VirtualMachineSM.reset()
        del InterfaceRouteTableSM._cassandra
        del VirtualMachineSM._cassandra

    def test_virtual_machine_create(self):
        test_utils.create_test_project('fake-domain:fake-project')
        test_utils.create_test_security_group(
            'fake-domain:fake-project:default')
        test_utils.create_test_virtual_network(
            'fake-domain:fake-project:left-vn')
        test_utils.create_test_virtual_network(
            'fake-domain:fake-project:right-vn')

        st = test_utils.create_test_st(name='vm-template',
                                       virt_type='virtual-machine',
                                       intf_list=[['management', False],
                                                  ['left', True],
                                                  ['right', False]])
        si = test_utils.create_test_si(name='vm-instance',
                                       count=2,
                                       intf_list=['', 'left-vn', 'right-vn'])

        def nova_oper(resource, oper, proj_name, **kwargs):
            if resource == 'servers' and oper == 'create':
                nova_vm = test_utils.FakeNovaServer('fake-vm-uuid',
                                                    kwargs['name'])
                return nova_vm
            else:
                return mock.MagicMock()

        self.nova_mock.oper = nova_oper

        self.vm_manager.create_service(st, si)
        self.mocked_vnc.virtual_machine_create.assert_any_call(
            test_utils.VMObjMatcher(1))
        self.mocked_vnc.virtual_machine_create.assert_any_call(
            test_utils.VMObjMatcher(2))
        self.assertTrue(si.availability_zone, 'default-availability-zone')

    def test_virtual_machine_delete(self):
        vm = test_utils.create_test_virtual_machine('fake-vm-uuid')
        self.vm_manager.delete_service(vm)

    def test_missing_image_in_template(self):
        test_utils.create_test_project('fake-domain:fake-project')
        test_utils.create_test_security_group(
            'fake-domain:fake-project:default')
        test_utils.create_test_virtual_network(
            'fake-domain:fake-project:left-vn')
        test_utils.create_test_virtual_network(
            'fake-domain:fake-project:right-vn')

        st = test_utils.create_test_st(name='vm-template',
                                       virt_type='virtual-machine',
                                       intf_list=[['management', False],
                                                  ['left', True],
                                                  ['right', False]])
        si = test_utils.create_test_si(name='vm-instance',
                                       count=2,
                                       intf_list=['', 'left-vn', 'right-vn'])

        st.params['image_name'] = None
        self.vm_manager.create_service(st, si)
        self.log_mock.error.assert_called_with("Image not present in %s" %
                                               ((':').join(st.fq_name)))

    def test_missing_image_in_nova(self):
        test_utils.create_test_project('fake-domain:fake-project')
        test_utils.create_test_security_group(
            'fake-domain:fake-project:default')
        test_utils.create_test_virtual_network(
            'fake-domain:fake-project:left-vn')
        test_utils.create_test_virtual_network(
            'fake-domain:fake-project:right-vn')

        st = test_utils.create_test_st(name='vm-template',
                                       virt_type='virtual-machine',
                                       intf_list=[['management', False],
                                                  ['left', True],
                                                  ['right', False]])
        si = test_utils.create_test_si(name='vm-instance',
                                       count=2,
                                       intf_list=['', 'left-vn', 'right-vn'])

        def nova_oper(resource, oper, proj_name, **kwargs):
            if resource == 'images' and oper == 'find':
                return None
            else:
                return mock.MagicMock()

        self.nova_mock.oper = nova_oper

        self.vm_manager.create_service(st, si)
        self.log_mock.error.assert_called_with("Image not found %s" % si.image)

    def test_nova_vm_create_fail(self):
        test_utils.create_test_project('fake-domain:fake-project')
        test_utils.create_test_security_group(
            'fake-domain:fake-project:default')
        test_utils.create_test_virtual_network(
            'fake-domain:fake-project:left-vn')
        test_utils.create_test_virtual_network(
            'fake-domain:fake-project:right-vn')

        st = test_utils.create_test_st(name='vm-template',
                                       virt_type='virtual-machine',
                                       intf_list=[['management', False],
                                                  ['left', True],
                                                  ['right', False]])
        si = test_utils.create_test_si(name='vm-instance',
                                       count=2,
                                       intf_list=['', 'left-vn', 'right-vn'])

        def nova_oper(resource, oper, proj_name, **kwargs):
            if resource == 'servers' and oper == 'create':
                return None
            else:
                return mock.MagicMock()

        self.nova_mock.oper = nova_oper

        self.vm_manager.create_service(st, si)
        self.log_mock.error.assert_any_call(
            test_utils.AnyStringWith('Nova vm create failed'))

    def test_missing_flavor_in_template(self):
        test_utils.create_test_project('fake-domain:fake-project')
        test_utils.create_test_security_group(
            'fake-domain:fake-project:default')
        test_utils.create_test_virtual_network(
            'fake-domain:fake-project:left-vn')
        test_utils.create_test_virtual_network(
            'fake-domain:fake-project:right-vn')

        st = test_utils.create_test_st(name='vm-template',
                                       virt_type='virtual-machine',
                                       intf_list=[['management', False],
                                                  ['left', True],
                                                  ['right', False]])
        si = test_utils.create_test_si(name='vm-instance',
                                       count=2,
                                       intf_list=['', 'left-vn', 'right-vn'])

        def nova_oper(resource, oper, proj_name, **kwargs):
            if resource == 'flavors' and oper == 'find':
                return None
            else:
                return mock.MagicMock()

        self.nova_mock.oper = nova_oper

        st.params['flavor'] = None
        self.vm_manager.create_service(st, si)
        self.log_mock.error.assert_called_with(
            test_utils.AnyStringWith("Flavor not found"))

    def test_availability_zone_setting(self):
        test_utils.create_test_project('fake-domain:fake-project')
        test_utils.create_test_security_group(
            'fake-domain:fake-project:default')
        test_utils.create_test_virtual_network(
            'fake-domain:fake-project:left-vn')
        test_utils.create_test_virtual_network(
            'fake-domain:fake-project:right-vn')

        st = test_utils.create_test_st(name='vm-template',
                                       virt_type='virtual-machine',
                                       intf_list=[['management', False],
                                                  ['left', True],
                                                  ['right', False]])
        si = test_utils.create_test_si(name='vm-instance',
                                       count=2,
                                       intf_list=['', 'left-vn', 'right-vn'])

        def nova_oper(resource, oper, proj_name, **kwargs):
            if resource == 'servers' and oper == 'create':
                nova_vm = test_utils.FakeNovaServer('fake-vm-uuid',
                                                    kwargs['name'])
                return nova_vm
            else:
                return mock.MagicMock()

        self.nova_mock.oper = nova_oper

        st.params['availability_zone_enable'] = True
        si.params['availability_zone'] = 'test-availability-zone'
        self.vm_manager.create_service(st, si)
        self.assertTrue(si.availability_zone, 'test-availability-zone')

    def test_network_config_validation(self):
        test_utils.create_test_project('fake-domain:fake-project')
        test_utils.create_test_security_group(
            'fake-domain:fake-project:default')
        test_utils.create_test_virtual_network(
            'fake-domain:fake-project:left-vn')
        test_utils.create_test_virtual_network(
            'fake-domain:fake-project:right-vn')

        st = test_utils.create_test_st(name='vm-template',
                                       virt_type='virtual-machine',
                                       intf_list=[['management', False],
                                                  ['left', True],
                                                  ['right', False]])
        si = test_utils.create_test_si(name='vm-instance',
                                       count=2,
                                       intf_list=['', 'left-vn', 'right-vn'])

        st.params['interface_type'] = []
        self.vm_manager.create_service(st, si)
        self.log_mock.notice.assert_called_with(
            "Interface list empty for ST %s SI %s" % ((':').join(st.fq_name),
                                                      (':').join(si.fq_name)))

    def test_virtual_machine_exists(self):
        test_utils.create_test_project('fake-domain:fake-project')
        test_utils.create_test_security_group(
            'fake-domain:fake-project:default')
        test_utils.create_test_virtual_network(
            'fake-domain:fake-project:left-vn')
        test_utils.create_test_virtual_network(
            'fake-domain:fake-project:right-vn')

        st = test_utils.create_test_st(name='vm-template',
                                       virt_type='virtual-machine',
                                       intf_list=[['management', False],
                                                  ['left', True],
                                                  ['right', False]])
        si = test_utils.create_test_si(name='vm-instance',
                                       count=2,
                                       intf_list=['', 'left-vn', 'right-vn'])

        def nova_oper(resource, oper, proj_name, **kwargs):
            if resource == 'servers' and oper == 'create':
                nova_vm = test_utils.FakeNovaServer(kwargs['name'],
                                                    kwargs['name'])
                return nova_vm
            else:
                return mock.MagicMock()

        self.nova_mock.oper = nova_oper

        self.mocked_vnc.virtual_machine_create = test_utils.vm_create

        self.vm_manager.create_service(st, si)
        self.log_mock.info.assert_any_call(
            test_utils.AnyStringWith('Launching VM :'))
        self.log_mock.info.assert_any_call(
            test_utils.AnyStringWith('Created VM :'))
        self.log_mock.info.assert_any_call(test_utils.AnyStringWith(si.name))
        self.log_mock.reset_mock()

        self.vm_manager.create_service(st, si)
        self.assertTrue(self.log_mock.info.call_count, 1)

    def test_virtual_machine_static_routes(self):
        test_utils.create_test_project('fake-domain:fake-project')
        test_utils.create_test_security_group(
            'fake-domain:fake-project:default')
        test_utils.create_test_virtual_network(
            'fake-domain:fake-project:left-vn')
        test_utils.create_test_virtual_network(
            'fake-domain:fake-project:right-vn')

        st = test_utils.create_test_st(name='vm-template',
                                       virt_type='virtual-machine',
                                       intf_list=[['management', False],
                                                  ['left', True, True],
                                                  ['right', False]])
        si = test_utils.create_test_si(name='vm-instance',
                                       count=2,
                                       intf_list=['', 'left-vn', 'right-vn'])

        def nova_oper(resource, oper, proj_name, **kwargs):
            if resource == 'servers' and oper == 'create':
                nova_vm = test_utils.FakeNovaServer('fake-vm-uuid',
                                                    kwargs['name'])
                return nova_vm
            else:
                return mock.MagicMock()

        self.nova_mock.oper = nova_oper

        self.vm_manager.create_service(st, si)
        self.mocked_vnc.virtual_machine_create.assert_any_call(
            test_utils.VMObjMatcher(1))
        self.mocked_vnc.virtual_machine_create.assert_any_call(
            test_utils.VMObjMatcher(2))
class VirtualMachineManagerTest(unittest.TestCase):
    def setUp(self):
        def get_vn_id(obj_type, fq_name):
            if obj_type != 'virtual-network':
                return
            for vn in VirtualNetworkSM.values():
                if vn.fq_name == fq_name:
                    return vn.uuid
            raise NoIdError(fq_name)

        def vn_create(vn_obj):
            vn_obj.uuid = (':').join(vn_obj.fq_name)
            vn = {}
            vn['uuid'] = vn_obj.uuid
            vn['fq_name'] = vn_obj.fq_name
            VirtualNetworkSM.locate(vn_obj.uuid, vn)
            return

        def vmi_create(vmi_obj):
            vmi_obj.uuid = 'fake-vmi-uuid'
            return

        self.mocked_vnc = mock.MagicMock()
        self.mocked_vnc.fq_name_to_id = get_vn_id
        self.mocked_vnc.virtual_network_create = vn_create
        self.mocked_vnc.virtual_machine_interface_create = vmi_create

        self.nova_mock = mock.MagicMock()
        self.mocked_db = mock.MagicMock()

        self.mocked_args = mock.MagicMock()
        self.mocked_args.availability_zone = None

        self.vm_manager = VirtualMachineManager(
            db=self.mocked_db, logger=mock.MagicMock(),
            vnc_lib=self.mocked_vnc, vrouter_scheduler=mock.MagicMock(),
            nova_client=self.nova_mock, args=self.mocked_args)

    def tearDown(self):
        ServiceTemplateSM.delete('fake-st-uuid')
        ServiceInstanceSM.delete('fake-si-uuid')
        pass

    def create_test_project(self, fq_name_str):
        proj_obj = {}
        proj_obj['fq_name'] = fq_name_str.split(':')
        proj_obj['uuid'] = fq_name_str
        proj_obj['id_perms'] = 'fake-id-perms'
        ProjectSM.locate(proj_obj['uuid'], proj_obj)

    def create_test_virtual_network(self, fq_name_str):
        vn_obj = {}
        vn_obj['fq_name'] = fq_name_str.split(':')
        vn_obj['uuid'] = fq_name_str
        vn_obj['id_perms'] = 'fake-id-perms'
        VirtualNetworkSM.locate(vn_obj['uuid'], vn_obj)

    def create_test_virtual_machine(self, fq_name_str):
        vm_obj = {}
        vm_obj['fq_name'] = fq_name_str.split(':')
        vm_obj['uuid'] = fq_name_str
        vm_obj['display_name'] = fq_name_str
        vm = VirtualMachineSM.locate(vm_obj['uuid'], vm_obj)
        vm.proj_fq_name = ['fake-domain', 'fake-project']
        return vm

    def test_create(self):
        self.create_test_project('fake-domain:fake-project')
        self.create_test_virtual_network('fake-domain:fake-project:left-vn')
        self.create_test_virtual_network('fake-domain:fake-project:right-vn')

        st_obj = {}
        st_obj['fq_name'] = ['fake-domain', 'fake-template']
        st_obj['uuid'] = 'fake-st-uuid'
        st_obj['id_perms'] = 'fake-id-perms'
        st_props = {}
        st_props['flavor'] = 'm1.medium'
        st_props['image'] = 'nat-image'
        st_props['service_virtualization_type'] = 'virtual-machine'
        st_props['service_type'] = 'firewall'
        st_props['ordered_interfaces'] = True
        st_props['interface_type'] = [{'service_interface_type': 'management', 'shared_ip': False},
                                      {'service_interface_type': 'left', 'shared_ip': False},
                                      {'service_interface_type': 'right', 'shared_ip': False}]
        st_obj['service_template_properties'] = st_props

        si_obj = {}
        si_obj['fq_name'] = ['fake-domain', 'fake-project', 'fake-instance']
        si_obj['uuid'] = 'fake-si-uuid'
        si_obj['id_perms'] = 'fake-id-perms'
        si_props = {}
        si_props['scale_out'] = {'max_instances': 2}
        si_props['interface_list'] = [{'virtual_network': None},
                                      {'virtual_network': 'fake-domain:fake-project:left-vn'},
                                      {'virtual_network': 'fake-domain:fake-project:right-vn'}]
        si_obj['service_instance_properties'] = si_props

        st = ServiceTemplateSM.locate('fake-st-uuid', st_obj)
        si = ServiceInstanceSM.locate('fake-si-uuid', si_obj)

        def nova_oper(resource, oper, proj_name, **kwargs):
            if resource == 'servers' and oper == 'create':
                nova_vm = FakeNovaServer('fake-vm-uuid', kwargs['name'])
                return nova_vm
            else:
                return mock.MagicMock()
        self.nova_mock.oper = nova_oper

        self.vm_manager.create_service(st, si)
        self.mocked_vnc.virtual_machine_create.assert_any_call(VMObjMatcher(1))
        self.mocked_vnc.virtual_machine_create.assert_any_call(VMObjMatcher(2))

    def test_delete(self):
        vm = self.create_test_virtual_machine('fake-vm-uuid')
        self.vm_manager.delete_service(vm)
class VirtualMachineManagerTest(unittest.TestCase):
    def setUp(self):
        VirtualMachineSM._cassandra = mock.MagicMock()
        VirtualMachineSM._cassandra.object_read = test_utils.vm_db_read
        VirtualMachineInterfaceSM._cassandra = mock.MagicMock()
        VirtualMachineInterfaceSM._cassandra.object_read = test_utils.vmi_db_read
        InstanceIpSM._cassandra = mock.MagicMock()
        InstanceIpSM._cassandra.object_read = test_utils.iip_db_read
        InterfaceRouteTableSM._cassandra = mock.MagicMock()
        InterfaceRouteTableSM._cassandra.object_read = test_utils.irt_db_read
        self.mocked_vnc = mock.MagicMock()
        self.mocked_vnc.fq_name_to_id = test_utils.get_vn_id_for_fq_name
        self.mocked_vnc.virtual_network_create = test_utils.vn_create
        self.mocked_vnc.virtual_machine_interface_create = test_utils.vmi_create
        self.mocked_vnc.instance_ip_create = test_utils.iip_create

        self.nova_mock = mock.MagicMock()
        self.mocked_db = mock.MagicMock()

        self.mocked_args = mock.MagicMock()
        self.mocked_args.availability_zone = 'default-availability-zone'

        self.log_mock = mock.MagicMock()

        self.vm_manager = VirtualMachineManager(
            db=self.mocked_db, logger=self.log_mock,
            vnc_lib=self.mocked_vnc, vrouter_scheduler=mock.MagicMock(),
            nova_client=self.nova_mock, args=self.mocked_args,
            agent_manager=mock.MagicMock())

    def tearDown(self):
        ServiceTemplateSM.reset()
        ServiceInstanceSM.reset()
        InstanceIpSM.reset()
        VirtualMachineInterfaceSM.reset()
        VirtualMachineSM.reset()
        del InterfaceRouteTableSM._cassandra
        del VirtualMachineSM._cassandra

    def test_virtual_machine_create(self):
        test_utils.create_test_project('fake-domain:fake-project')
        test_utils.create_test_security_group('fake-domain:fake-project:default')
        test_utils.create_test_virtual_network('fake-domain:fake-project:left-vn')
        test_utils.create_test_virtual_network('fake-domain:fake-project:right-vn')

        st = test_utils.create_test_st(name='vm-template',
            virt_type='virtual-machine',
            intf_list=[['management', False], ['left', True], ['right', False]])
        si = test_utils.create_test_si(name='vm-instance', count=2,
            intf_list=['', 'left-vn', 'right-vn'])

        def nova_oper(resource, oper, proj_name, **kwargs):
            if resource == 'servers' and oper == 'create':
                nova_vm = test_utils.FakeNovaServer('fake-vm-uuid', kwargs['name'])
                return nova_vm
            else:
                return mock.MagicMock()
        self.nova_mock.oper = nova_oper

        self.vm_manager.create_service(st, si)
        self.mocked_vnc.virtual_machine_create.assert_any_call(test_utils.VMObjMatcher(1))
        self.mocked_vnc.virtual_machine_create.assert_any_call(test_utils.VMObjMatcher(2))
        self.assertTrue(si.availability_zone, 'default-availability-zone') 

    def test_virtual_machine_delete(self):
        vm = test_utils.create_test_virtual_machine('fake-vm-uuid')
        self.vm_manager.delete_service(vm)

    def test_missing_image_in_template(self):
        test_utils.create_test_project('fake-domain:fake-project')
        test_utils.create_test_security_group('fake-domain:fake-project:default')
        test_utils.create_test_virtual_network('fake-domain:fake-project:left-vn')
        test_utils.create_test_virtual_network('fake-domain:fake-project:right-vn')

        st = test_utils.create_test_st(name='vm-template',
            virt_type='virtual-machine',
            intf_list=[['management', False], ['left', True], ['right', False]])
        si = test_utils.create_test_si(name='vm-instance', count=2,
            intf_list=['', 'left-vn', 'right-vn'])

        st.params['image_name'] = None
        self.vm_manager.create_service(st, si)
        self.log_mock.log_error.assert_called_with("Image not present in %s" % ((':').join(st.fq_name)))

    def test_missing_image_in_nova(self):
        test_utils.create_test_project('fake-domain:fake-project')
        test_utils.create_test_security_group('fake-domain:fake-project:default')
        test_utils.create_test_virtual_network('fake-domain:fake-project:left-vn')
        test_utils.create_test_virtual_network('fake-domain:fake-project:right-vn')

        st = test_utils.create_test_st(name='vm-template',
            virt_type='virtual-machine',
            intf_list=[['management', False], ['left', True], ['right', False]])
        si = test_utils.create_test_si(name='vm-instance', count=2,
            intf_list=['', 'left-vn', 'right-vn'])

        def nova_oper(resource, oper, proj_name, **kwargs):
            if resource == 'images' and oper == 'find':
                return None
            else:
                return mock.MagicMock()
        self.nova_mock.oper = nova_oper

        self.vm_manager.create_service(st, si)
        self.log_mock.log_error.assert_called_with("Image not found %s" % si.image)

    def test_nova_vm_create_fail(self):
        test_utils.create_test_project('fake-domain:fake-project')
        test_utils.create_test_security_group('fake-domain:fake-project:default')
        test_utils.create_test_virtual_network('fake-domain:fake-project:left-vn')
        test_utils.create_test_virtual_network('fake-domain:fake-project:right-vn')

        st = test_utils.create_test_st(name='vm-template',
            virt_type='virtual-machine',
            intf_list=[['management', False], ['left', True], ['right', False]])
        si = test_utils.create_test_si(name='vm-instance', count=2,
            intf_list=['', 'left-vn', 'right-vn'])

        def nova_oper(resource, oper, proj_name, **kwargs):
            if resource == 'servers' and oper == 'create':
                return None
            else:
                return mock.MagicMock()
        self.nova_mock.oper = nova_oper

        self.vm_manager.create_service(st, si)
        self.log_mock.log_error.assert_any_call(test_utils.AnyStringWith('Nova vm create failed'))

    def test_missing_flavor_in_template(self):
        test_utils.create_test_project('fake-domain:fake-project')
        test_utils.create_test_security_group('fake-domain:fake-project:default')
        test_utils.create_test_virtual_network('fake-domain:fake-project:left-vn')
        test_utils.create_test_virtual_network('fake-domain:fake-project:right-vn')

        st = test_utils.create_test_st(name='vm-template',
            virt_type='virtual-machine',
            intf_list=[['management', False], ['left', True], ['right', False]])
        si = test_utils.create_test_si(name='vm-instance', count=2,
            intf_list=['', 'left-vn', 'right-vn'])

        def nova_oper(resource, oper, proj_name, **kwargs):
            if resource == 'flavors' and oper == 'find':
                return None
            else:
                return mock.MagicMock()
        self.nova_mock.oper = nova_oper

        st.params['flavor'] = None
        self.vm_manager.create_service(st, si)
        self.log_mock.log_error.assert_called_with(test_utils.AnyStringWith("Flavor not found"))

    def test_availability_zone_setting(self):
        test_utils.create_test_project('fake-domain:fake-project')
        test_utils.create_test_security_group('fake-domain:fake-project:default')
        test_utils.create_test_virtual_network('fake-domain:fake-project:left-vn')
        test_utils.create_test_virtual_network('fake-domain:fake-project:right-vn')

        st = test_utils.create_test_st(name='vm-template',
            virt_type='virtual-machine',
            intf_list=[['management', False], ['left', True], ['right', False]])
        si = test_utils.create_test_si(name='vm-instance', count=2,
            intf_list=['', 'left-vn', 'right-vn'])

        def nova_oper(resource, oper, proj_name, **kwargs):
            if resource == 'servers' and oper == 'create':
                nova_vm = test_utils.FakeNovaServer('fake-vm-uuid', kwargs['name'])
                return nova_vm
            else:
                return mock.MagicMock()
        self.nova_mock.oper = nova_oper

        st.params['availability_zone_enable'] = True
        si.params['availability_zone'] = 'test-availability-zone'
        self.vm_manager.create_service(st, si)
        self.assertTrue(si.availability_zone, 'test-availability-zone') 

    def test_network_config_validation(self):
        test_utils.create_test_project('fake-domain:fake-project')
        test_utils.create_test_security_group('fake-domain:fake-project:default')
        test_utils.create_test_virtual_network('fake-domain:fake-project:left-vn')
        test_utils.create_test_virtual_network('fake-domain:fake-project:right-vn')

        st = test_utils.create_test_st(name='vm-template',
            virt_type='virtual-machine',
            intf_list=[['management', False], ['left', True], ['right', False]])
        si = test_utils.create_test_si(name='vm-instance', count=2,
            intf_list=['', 'left-vn', 'right-vn'])

        st.params['interface_type'] = []
        self.vm_manager.create_service(st, si)
        self.log_mock.log_notice.assert_called_with("Interface list empty for ST %s SI %s" %
            ((':').join(st.fq_name), (':').join(si.fq_name)))

    def test_virtual_machine_exists(self):
        test_utils.create_test_project('fake-domain:fake-project')
        test_utils.create_test_security_group('fake-domain:fake-project:default')
        test_utils.create_test_virtual_network('fake-domain:fake-project:left-vn')
        test_utils.create_test_virtual_network('fake-domain:fake-project:right-vn')

        st = test_utils.create_test_st(name='vm-template',
            virt_type='virtual-machine',
            intf_list=[['management', False], ['left', True], ['right', False]])
        si = test_utils.create_test_si(name='vm-instance', count=2,
            intf_list=['', 'left-vn', 'right-vn'])

        def nova_oper(resource, oper, proj_name, **kwargs):
            if resource == 'servers' and oper == 'create':
                nova_vm = test_utils.FakeNovaServer(kwargs['name'], kwargs['name'])
                return nova_vm
            else:
                return mock.MagicMock()
        self.nova_mock.oper = nova_oper

        self.mocked_vnc.virtual_machine_create = test_utils.vm_create

        self.vm_manager.create_service(st, si)
        self.log_mock.log_info.assert_any_call(test_utils.AnyStringWith('Launching VM :'))
        self.log_mock.log_info.assert_any_call(test_utils.AnyStringWith('Created VM :'))
        self.log_mock.log_info.assert_any_call(test_utils.AnyStringWith(si.name))
        self.log_mock.reset_mock()

        self.vm_manager.create_service(st, si)
        self.assertTrue(self.log_mock.log_info.call_count, 1)

    def test_virtual_machine_static_routes(self):
        test_utils.create_test_project('fake-domain:fake-project')
        test_utils.create_test_security_group('fake-domain:fake-project:default')
        test_utils.create_test_virtual_network('fake-domain:fake-project:left-vn')
        test_utils.create_test_virtual_network('fake-domain:fake-project:right-vn')

        st = test_utils.create_test_st(name='vm-template',
            virt_type='virtual-machine',
            intf_list=[['management', False], ['left', True, True], ['right', False]])
        si = test_utils.create_test_si(name='vm-instance', count=2,
            intf_list=['', 'left-vn', 'right-vn'])

        def nova_oper(resource, oper, proj_name, **kwargs):
            if resource == 'servers' and oper == 'create':
                nova_vm = test_utils.FakeNovaServer('fake-vm-uuid', kwargs['name'])
                return nova_vm
            else:
                return mock.MagicMock()
        self.nova_mock.oper = nova_oper

        self.vm_manager.create_service(st, si)
        self.mocked_vnc.virtual_machine_create.assert_any_call(test_utils.VMObjMatcher(1))
        self.mocked_vnc.virtual_machine_create.assert_any_call(test_utils.VMObjMatcher(2))
class VirtualMachineManagerTest(unittest.TestCase):
    def setUp(self):
        def get_vn_id(obj_type, fq_name):
            if obj_type != 'virtual-network':
                return
            for vn in VirtualNetworkSM.values():
                if vn.fq_name == fq_name:
                    return vn.uuid
            raise NoIdError(fq_name)

        def vn_create(vn_obj):
            vn_obj.uuid = (':').join(vn_obj.fq_name)
            vn = {}
            vn['uuid'] = vn_obj.uuid
            vn['fq_name'] = vn_obj.fq_name
            VirtualNetworkSM.locate(vn_obj.uuid, vn)
            return

        def vmi_create(vmi_obj):
            vmi_obj.uuid = 'fake-vmi-uuid'
            return

        def iip_create(iip_obj):
            iip_obj.uuid = 'fake-iip-uuid'
            return

        self.mocked_vnc = mock.MagicMock()
        self.mocked_vnc.fq_name_to_id = get_vn_id
        self.mocked_vnc.virtual_network_create = vn_create
        self.mocked_vnc.virtual_machine_interface_create = vmi_create
        self.mocked_vnc.instance_ip_create = iip_create

        self.nova_mock = mock.MagicMock()
        self.mocked_db = mock.MagicMock()

        self.mocked_args = mock.MagicMock()
        self.mocked_args.availability_zone = 'default-availability-zone'

        self.log_mock = mock.MagicMock()

        self.vm_manager = VirtualMachineManager(
            db=self.mocked_db, logger=self.log_mock,
            vnc_lib=self.mocked_vnc, vrouter_scheduler=mock.MagicMock(),
            nova_client=self.nova_mock, args=self.mocked_args)

    def tearDown(self):
        ServiceTemplateSM.delete('fake-st-uuid')
        ServiceInstanceSM.delete('fake-si-uuid')
        pass

    def create_test_project(self, fq_name_str):
        proj_obj = {}
        proj_obj['fq_name'] = fq_name_str.split(':')
        proj_obj['uuid'] = fq_name_str
        proj_obj['id_perms'] = 'fake-id-perms'
        ProjectSM.locate(proj_obj['uuid'], proj_obj)

    def create_test_virtual_network(self, fq_name_str):
        vn_obj = {}
        vn_obj['fq_name'] = fq_name_str.split(':')
        vn_obj['uuid'] = fq_name_str
        vn_obj['id_perms'] = 'fake-id-perms'
        VirtualNetworkSM.locate(vn_obj['uuid'], vn_obj)

    def create_test_virtual_machine(self, fq_name_str):
        vm_obj = {}
        vm_obj['fq_name'] = fq_name_str.split(':')
        vm_obj['uuid'] = fq_name_str
        vm_obj['display_name'] = fq_name_str
        vm = VirtualMachineSM.locate(vm_obj['uuid'], vm_obj)
        vm.proj_fq_name = ['fake-domain', 'fake-project']
        return vm

    def create_test_st_obj(self):
        st_obj = {}
        st_obj['fq_name'] = ['fake-domain', 'fake-template']
        st_obj['uuid'] = 'fake-st-uuid'
        st_obj['id_perms'] = 'fake-id-perms'
        st_props = {}
        st_props['flavor'] = 'm1.medium'
        st_props['image_name'] = 'nat-image'
        st_props['service_virtualization_type'] = 'virtual-machine'
        st_props['service_type'] = 'firewall'
        st_props['ordered_interfaces'] = True
        st_props['interface_type'] = [{'service_interface_type': 'management', 'shared_ip': False},
                                      {'service_interface_type': 'left', 'shared_ip': False},
                                      {'service_interface_type': 'right', 'shared_ip': False}]
        st_obj['service_template_properties'] = st_props
        st = ServiceTemplateSM.locate('fake-st-uuid', st_obj)
        return st

    def create_test_si_obj(self, name='fake-instance'):
        si_obj = {}
        si_obj['fq_name'] = ['fake-domain', 'fake-project', name]
        si_obj['uuid'] = name
        si_obj['id_perms'] = 'fake-id-perms'
        si_props = {}
        si_props['scale_out'] = {'max_instances': 2}
        si_props['interface_list'] = [{'virtual_network': None},
                                      {'virtual_network': 'fake-domain:fake-project:left-vn'},
                                      {'virtual_network': 'fake-domain:fake-project:right-vn'}]
        si_obj['service_instance_properties'] = si_props
        si = ServiceInstanceSM.locate('fake-si-uuid', si_obj)
        return si

    def test_virtual_machine_create(self):
        self.create_test_project('fake-domain:fake-project')
        self.create_test_virtual_network('fake-domain:fake-project:left-vn')
        self.create_test_virtual_network('fake-domain:fake-project:right-vn')
        st = self.create_test_st_obj()
        si = self.create_test_si_obj()

        def nova_oper(resource, oper, proj_name, **kwargs):
            if resource == 'servers' and oper == 'create':
                nova_vm = FakeNovaServer('fake-vm-uuid', kwargs['name'])
                return nova_vm
            else:
                return mock.MagicMock()
        self.nova_mock.oper = nova_oper

        self.vm_manager.create_service(st, si)
        self.mocked_vnc.virtual_machine_create.assert_any_call(VMObjMatcher(1))
        self.mocked_vnc.virtual_machine_create.assert_any_call(VMObjMatcher(2))
        self.assertTrue(si.availability_zone, 'default-availability-zone') 

    def test_virtual_machine_delete(self):
        vm = self.create_test_virtual_machine('fake-vm-uuid')
        self.vm_manager.delete_service(vm)

    def test_missing_image_in_template(self):
        self.create_test_project('fake-domain:fake-project')
        self.create_test_virtual_network('fake-domain:fake-project:left-vn')
        self.create_test_virtual_network('fake-domain:fake-project:right-vn')
        st = self.create_test_st_obj()
        si = self.create_test_si_obj()

        st.params['image_name'] = None
        self.vm_manager.create_service(st, si)
        self.log_mock.log_error.assert_called_with("Image not present in %s" % ((':').join(st.fq_name)))

    def test_missing_flavor_in_template(self):
        self.create_test_project('fake-domain:fake-project')
        self.create_test_virtual_network('fake-domain:fake-project:left-vn')
        self.create_test_virtual_network('fake-domain:fake-project:right-vn')
        st = self.create_test_st_obj()
        si = self.create_test_si_obj()

        def nova_oper(resource, oper, proj_name, **kwargs):
            if resource == 'flavors' and oper == 'find':
                return None
            else:
                return mock.MagicMock()
        self.nova_mock.oper = nova_oper

        st.params['flavor'] = None
        self.vm_manager.create_service(st, si)
        self.log_mock.log_error.assert_called_with(AnyStringWith("Flavor not found"))

    def test_availability_zone_setting(self):
        self.create_test_project('fake-domain:fake-project')
        self.create_test_virtual_network('fake-domain:fake-project:left-vn')
        self.create_test_virtual_network('fake-domain:fake-project:right-vn')
        st = self.create_test_st_obj()
        si = self.create_test_si_obj()

        def nova_oper(resource, oper, proj_name, **kwargs):
            if resource == 'servers' and oper == 'create':
                nova_vm = FakeNovaServer('fake-vm-uuid', kwargs['name'])
                return nova_vm
            else:
                return mock.MagicMock()
        self.nova_mock.oper = nova_oper

        st.params['availability_zone_enable'] = True
        si.params['availability_zone'] = 'test-availability-zone'
        self.vm_manager.create_service(st, si)
        self.assertTrue(si.availability_zone, 'test-availability-zone') 

    def test_network_config_validation(self):
        self.create_test_project('fake-domain:fake-project')
        self.create_test_virtual_network('fake-domain:fake-project:left-vn')
        self.create_test_virtual_network('fake-domain:fake-project:right-vn')
        st = self.create_test_st_obj()
        si = self.create_test_si_obj()

        st.params['interface_type'] = []
        self.vm_manager.create_service(st, si)
        self.log_mock.log_notice.assert_called_with("Interface list empty for ST %s SI %s" %
            ((':').join(st.fq_name), (':').join(si.fq_name)))

    def test_virtual_machine_exists(self):
        self.create_test_project('fake-domain:fake-project')
        self.create_test_virtual_network('fake-domain:fake-project:left-vn')
        self.create_test_virtual_network('fake-domain:fake-project:right-vn')
        st = self.create_test_st_obj()
        si = self.create_test_si_obj()

        def nova_oper(resource, oper, proj_name, **kwargs):
            if resource == 'servers' and oper == 'create':
                nova_vm = FakeNovaServer(kwargs['name'], kwargs['name'])
                return nova_vm
            else:
                return mock.MagicMock()
        self.nova_mock.oper = nova_oper

        def vm_create(vm_obj):
            vm_obj.uuid = (':').join(vm_obj.fq_name)
            vm = {}
            vm['uuid'] = vm_obj.uuid
            vm['fq_name'] = vm_obj.fq_name
            vm['display_name'] = vm_obj.display_name
            VirtualMachineSM.locate(vm_obj.uuid, vm)
            si = ServiceInstanceSM.get(vm_obj.get_service_instance_refs()[0]['uuid'])
            if si:
                si.virtual_machines.add(vm_obj.uuid)
                vm_db = VirtualMachineSM.locate(vm_obj.uuid)
                vm_db.index = int(vm_obj.display_name.split('__')[-2]) - 1
            return
        self.mocked_vnc.virtual_machine_create = vm_create

        self.vm_manager.create_service(st, si)
        self.log_mock.log_info.assert_any_call(AnyStringWith('Launching VM :'))
        self.log_mock.log_info.assert_any_call(AnyStringWith('Created VM :'))
        self.log_mock.log_info.assert_any_call(AnyStringWith(si.name))
        self.log_mock.reset_mock()

        self.vm_manager.create_service(st, si)
        self.assertTrue(self.log_mock.log_info.call_count, 1)