def test_plugins_exception_with_unload(caplog): plugins = load_plugins( { 'please_dont_make_a_plugin_called_this': {'unload_on_init_exception': True}, 'identityplugin': {}, }, 'mock_probe', ) assert len(plugins) == 1 assert isinstance(plugins[0], Identityplugin) assert 'Could not import [\'pidtree_bcc.plugins.please_dont_make_a_plugin_called_this\']' in caplog.text
def test_plugins_loads_multiple_plugins(): plugins = load_plugins( { 'identityplugin': {}, 'sourceipmap': { 'hostfiles': ['/etc/hosts'], }, }, 'tcp_connect', ) assert len(plugins) == 2
def __init__( self, output_queue: SimpleQueue, probe_config: dict = None, lost_event_telemetry: int = -1, config_change_queue: SimpleQueue = None, ): """ Constructor :param Queue output_queue: queue for event output :param dict probe_config: (optional) config passed as kwargs to BPF template all fields are passed to the template engine with the exception of "plugins". This behaviour can be overidden with the TEMPLATE_VARS class variable defining a list of config fields. It is possible for child class to define a CONFIG_DEFAULTS class variable containing default templating variables. :param int lost_event_telemetry: every how many messages emit the number of lost messages. Set to <= 0 to disable. :param SimpleQueue config_change_queue: queue for passing configuration changes """ self.SIDECARS = [] probe_config = probe_config if probe_config else {} self.output_queue = output_queue self.validate_config(probe_config) module_src = inspect.getsourcefile(type(self)) self.probe_name = os.path.basename(module_src).split('.')[0] self.plugins = load_plugins( probe_config.get('plugins', {}), self.probe_name, self.EXTRA_PLUGIN_PATH, ) if not hasattr(self, 'BPF_TEXT'): with open(re.sub(r'\.py$', '.j2', module_src)) as f: self.BPF_TEXT = f.read() template_config = self.build_probe_config(probe_config) jinja_env = Environment( loader=FileSystemLoader(os.path.dirname(module_src))) self.expanded_bpf_text = jinja_env.from_string( self.BPF_TEXT).render(**template_config) self.lost_event_telemetry = lost_event_telemetry self.lost_event_timer = lost_event_telemetry self.lost_event_count = 0 self.net_filter_mutex = Lock() if self.USES_DYNAMIC_FILTERS and config_change_queue: self.SIDECARS.append( (self._poll_config_changes, (config_change_queue, )))
def test_plugins_loads_no_plugins(): plugins = load_plugins({}, 'mock_probe') assert plugins == []
def test_plugins_load_incompatible(): with pytest.raises(RuntimeError): load_plugins({'sourceipmap': {}}, 'mock_probe')
def test_plugins_exception_on_no_file(): with pytest.raises(RuntimeError) as e: load_plugins({'please_dont_make_a_plugin_called_this': {}}, 'mock_probe') assert 'No module named ' in str(e)
def test_plugins_doesnt_load_disabled_identity_plugin(): plugins = load_plugins({'identityplugin': {'enabled': False}}, 'mock_probe') assert plugins == []
def test_plugins_loads_identity_plugin(): plugins = load_plugins({'identityplugin': {}}, 'mock_probe') assert isinstance(plugins[0], Identityplugin)