async def test_get_device_info_cache_exist(patch_register_plugins, plugin_context, clear_caches): """Get the existing device info cache.""" # create & register new plugin p = plugin.Plugin(metadata=api.Metadata(name='foo', tag='vaporio/foo'), address='localhost:9999', plugin_client=client.PluginTCPClient('localhost:9999')) p.client.devices = mock_client_devices # this is the first time we ask for cache # it's not there yet so we build one first_meta = await cache.get_device_info_cache() assert isinstance(first_meta, dict) assert 'rack-1-vec-12345' in first_meta assert first_meta['rack-1-vec-12345'] == mock_get_device_info_cache( )['rack-1-vec-12345'] # this is the second time we ask for it # it should be there this time and return right away second_meta = await cache.get_device_info_cache() assert isinstance(second_meta, dict) assert 'rack-1-vec-12345' in second_meta assert second_meta['rack-1-vec-12345'] == mock_get_device_info_cache( )['rack-1-vec-12345']
def test_make_channel_insecure(): """Test making the grpc channel for the plugin client. In this case, the channel will be insecure (no TLS configured). """ c = client.PluginTCPClient('localhost') assert c.channel is not None assert c.channel._channel.target() == b'localhost'
async def test_get_device_info_cache_partial_failure(patch_register_plugins, plugin_context, clear_caches): """Get the device info cache when some plugins fail to respond.""" # create & register new plugins p = plugin.Plugin(metadata=api.Metadata(name='foo', tag='vaporio/foo'), address='localhost:9999', plugin_client=client.PluginTCPClient('localhost:9999')) p.client.devices = mock_client_devices p = plugin.Plugin(metadata=api.Metadata(name='bar', tag='vaporio/bar'), address='localhost:9998', plugin_client=client.PluginTCPClient('localhost:9998')) p.client.devices = mock_client_device_info_fail # override to induce failure meta = await cache.get_device_info_cache() assert isinstance(meta, dict) assert len(meta) == 1 # two plugins registered, but only one successful
def test_make_channel_secure(): """Test making the grpc channel for the plugin client. In this case, the channel will be secure (TLS configured). """ crt = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'test_data', 'test.crt') config.options.set('grpc.tls.cert', crt) c = client.PluginTCPClient('localhost') assert c.channel is not None assert c.channel._channel.target() == b'localhost'
async def test_get_device_info_cache_empty(plugin_context, clear_caches): """Get the empty device info cache.""" # create & register new plugin p = plugin.Plugin(metadata=api.Metadata(name='foo', tag='vaporio/foo'), address='localhost:9999', plugin_client=client.PluginTCPClient('localhost:9999')) p.client.devices = mock_client_device_info_empty meta = await cache.get_device_info_cache() assert isinstance(meta, dict) assert len(meta) == 0
async def test_get_device_info_cache_total_failure(plugin_context, clear_caches): """Get the device info cache when all plugins fail to respond.""" # create & register new plugin p = plugin.Plugin(metadata=api.Metadata(name='foo', tag='vaporio/foo'), address='localhost:9999', plugin_client=client.PluginTCPClient('localhost:9999')) p.client.devices = mock_client_device_info_fail # override to induce failure try: await cache.get_device_info_cache() except errors.SynseError as e: assert e.error_id == errors.INTERNAL_API_FAILURE
def mock_plugin(): """Convenience fixture to create a test plugin. We create a TCP based plugin for ease of testing. """ p = plugin.Plugin( metadata=api.Metadata( name='test-plug', tag='vaporio/test-plug' ), address='localhost:9999', plugin_client=client.PluginTCPClient(address='localhost:9999') ) yield p
async def test_get_device_info_cache_ok(patch_register_plugins, plugin_context, clear_caches): """Get the device info cache.""" # create & register new plugin p = plugin.Plugin(metadata=api.Metadata(name='foo', tag='vaporio/foo'), address='localhost:9999', plugin_client=client.PluginTCPClient('localhost:9999')) p.client.devices = mock_client_devices meta = await cache.get_device_info_cache() assert isinstance(meta, dict) assert 'rack-1-vec-12345' in meta assert meta['rack-1-vec-12345'] == mock_get_device_info_cache( )['rack-1-vec-12345']
async def test_get_resource_info_cache_empty(plugin_context, clear_caches): """Get the empty info cache.""" # create & register new plugin with empty device info cache p = plugin.Plugin(metadata=api.Metadata(name='foo', tag='vaporio/foo'), address='localhost:9999', plugin_client=client.PluginTCPClient('localhost:9999')) p.client.devices = mock_client_device_info_empty meta_cache = await cache.get_device_info_cache() assert isinstance(meta_cache, dict) assert len(meta_cache) == 0 # because device info cache is empty and info cache is built upon device info's # scan cache should also be empty info_cache = await cache.get_resource_info_cache() assert isinstance(info_cache, dict) assert len(info_cache) == 0
def register_plugin(address, protocol): """Register a plugin. If a plugin with the given address already exists, it will not be re-registered, but its ID will still be returned. If a plugin fails to register, None is returned. Args: address (str): The address of the plugin to register. protocol (str): The protocol that the plugin uses. This should be one of 'unix', 'tcp'. Returns: str: The ID of the plugin that was registered. None: The given address failed to resolve, so no plugin was registered. Raises: ValueError: An invalid protocol is specified. The protocol must be one of: 'unix', 'tcp' """ plugin = Plugin.manager.get_by_address(address) if plugin: logger.debug(_('{} is already registered').format(plugin)) return plugin.id() # The client does not exist, so we must register it. This means we need to # connect with it to (a) make sure its reachable, and (b) get its metadata # in order to properly create a new Plugin model for it. if protocol == 'tcp': plugin_client = client.PluginTCPClient(address) elif protocol == 'unix': plugin_client = client.PluginUnixClient(address) else: raise ValueError(_('Invalid protocol specified for registration: {}').format(protocol)) try: status = plugin_client.test() if not status.ok: logger.warning(_('gRPC Test response was not OK: {}').format(address)) return None except Exception as e: logger.warning(_('Failed to reach plugin at address {}: {}').format(address, e)) return None # If we made it here, we were successful in establishing communication # with the plugin. Now, we should get its metainfo and create a Plugin # instance with it. try: meta = plugin_client.metainfo() except Exception as e: logger.warning(_('Failed to get plugin metadata at address {}: {}').format(address, e)) return None plugin = Plugin( metadata=meta, address=address, plugin_client=plugin_client ) logger.debug(_('Registered new plugin: {}').format(plugin)) return plugin.id()