diff --git a/include/fluent-bit/flb_plugin_alias.h b/include/fluent-bit/flb_plugin_alias.h new file mode 100644 index 00000000000..bd4746b2e3a --- /dev/null +++ b/include/fluent-bit/flb_plugin_alias.h @@ -0,0 +1,58 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +/* Fluent Bit + * ========== + * Copyright (C) 2015-2026 The Fluent Bit Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * 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. + */ + +#ifndef FLB_PLUGIN_ALIAS_H +#define FLB_PLUGIN_ALIAS_H + +#include + +/* + * Returned by flb_plugin_alias_rewrite() when an alias exists but an internal + * error prevents generating a rewritten string. + */ +#define FLB_PLUGIN_ALIAS_ERR ((char *) -1) + +struct flb_plugin_alias_entry { + int plugin_type; + const char *alias_name; + const char *plugin_name; +}; + +/* + * Returns the canonical plugin name for alias_name when a mapping exists, + * otherwise returns NULL. + */ +const char *flb_plugin_alias_get(int plugin_type, const char *alias_name, + size_t alias_name_length); + +/* + * Rewrites plugin_reference when it starts with a known alias. + * + * Return values: + * - NULL: no rewrite needed + * - FLB_PLUGIN_ALIAS_ERR: rewrite needed but failed + * - allocated string: rewritten plugin reference (caller must free) + */ +char *flb_plugin_alias_rewrite(int plugin_type, const char *plugin_reference); + +void flb_plugin_alias_set_custom_entries( + const struct flb_plugin_alias_entry *entries); +void flb_plugin_alias_reset_custom_entries(void); + +#endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a47a5d9d658..8b0078afbc5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -67,6 +67,7 @@ set(src flb_crypto.c flb_random.c flb_plugin.c + flb_plugin_alias.c flb_gzip.c flb_snappy.c flb_zstd.c diff --git a/src/flb_filter.c b/src/flb_filter.c index 79299885065..c58142cde8e 100644 --- a/src/flb_filter.c +++ b/src/flb_filter.c @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include #ifdef FLB_HAVE_CHUNK_TRACE @@ -435,6 +437,8 @@ struct flb_filter_instance *flb_filter_new(struct flb_config *config, const char *filter, void *data) { int id; + char *filter_name; + const char *effective_filter_name; struct mk_list *head; struct flb_filter_plugin *plugin; struct flb_filter_instance *instance = NULL; @@ -443,21 +447,35 @@ struct flb_filter_instance *flb_filter_new(struct flb_config *config, return NULL; } + filter_name = flb_plugin_alias_rewrite(FLB_PLUGIN_FILTER, filter); + if (filter_name == FLB_PLUGIN_ALIAS_ERR) { + return NULL; + } + + if (filter_name != NULL) { + effective_filter_name = filter_name; + } + else { + effective_filter_name = filter; + } + mk_list_foreach(head, &config->filter_plugins) { plugin = mk_list_entry(head, struct flb_filter_plugin, _head); - if (strcasecmp(plugin->name, filter) == 0) { + if (strcasecmp(plugin->name, effective_filter_name) == 0) { break; } plugin = NULL; } if (!plugin) { + flb_free(filter_name); return NULL; } instance = flb_calloc(1, sizeof(struct flb_filter_instance)); if (!instance) { flb_errno(); + flb_free(filter_name); return NULL; } instance->config = config; @@ -493,6 +511,7 @@ struct flb_filter_instance *flb_filter_new(struct flb_config *config, mk_list_init(&instance->properties); mk_list_add(&instance->_head, &config->filters); + flb_free(filter_name); return instance; } diff --git a/src/flb_input.c b/src/flb_input.c index e990eee238c..c7eedf0cab1 100644 --- a/src/flb_input.c +++ b/src/flb_input.c @@ -44,6 +44,7 @@ #include #include #include +#include /* input plugin macro helpers */ #include @@ -275,6 +276,8 @@ struct flb_input_instance *flb_input_new(struct flb_config *config, int id; int ret; int flags = 0; + char *input_uri; + const char *input_name; struct mk_list *head; struct flb_input_plugin *plugin; struct flb_input_instance *instance = NULL; @@ -289,9 +292,21 @@ struct flb_input_instance *flb_input_new(struct flb_config *config, return NULL; } + input_uri = flb_plugin_alias_rewrite(FLB_PLUGIN_INPUT, input); + if (input_uri == FLB_PLUGIN_ALIAS_ERR) { + return NULL; + } + + if (input_uri != NULL) { + input_name = input_uri; + } + else { + input_name = input; + } + mk_list_foreach(head, &config->in_plugins) { plugin = mk_list_entry(head, struct flb_input_plugin, _head); - if (!check_protocol(plugin->name, input)) { + if (!check_protocol(plugin->name, input_name)) { plugin = NULL; continue; } @@ -301,6 +316,7 @@ struct flb_input_instance *flb_input_new(struct flb_config *config, * requirement. */ if (public_only == FLB_TRUE && plugin->flags & FLB_INPUT_PRIVATE) { + flb_free(input_uri); return NULL; } @@ -578,6 +594,7 @@ struct flb_input_instance *flb_input_new(struct flb_config *config, instance->test_formatter.callback = plugin->test_formatter.callback; } + flb_free(input_uri); return instance; } diff --git a/src/flb_network.c b/src/flb_network.c index 92aa601341c..abc8ef89e7c 100644 --- a/src/flb_network.c +++ b/src/flb_network.c @@ -161,6 +161,7 @@ int flb_net_host_set(const char *plugin_name, struct flb_net_host *host, const c int len; int olen; const char *s, *e, *u; + const char *separator; memset(host, '\0', sizeof(struct flb_net_host)); @@ -174,7 +175,16 @@ int flb_net_host_set(const char *plugin_name, struct flb_net_host *host, const c return -1; } - s = address + len; + separator = strchr(address, ':'); + if (separator != NULL && + separator != address && + separator[1] == '/' && + separator[2] == '/') { + s = separator + 3; + } + else { + s = address + len; + } if (*s == '[') { /* IPv6 address (RFC 3986) */ e = strchr(++s, ']'); diff --git a/src/flb_output.c b/src/flb_output.c index 26f66ad9e36..2ea9e25aae5 100644 --- a/src/flb_output.c +++ b/src/flb_output.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -128,6 +129,7 @@ static int check_protocol(const char *prot, const char *output) { int len; char *p; + const char *alias_target; p = strstr(output, "://"); if (p && p != output) { @@ -137,12 +139,16 @@ static int check_protocol(const char *prot, const char *output) len = strlen(output); } - if (strlen(prot) != len) { - return 0; + /* Output plugin match */ + if (strlen(prot) == (size_t) len && + strncasecmp(prot, output, len) == 0) { + return 1; } - /* Output plugin match */ - if (strncasecmp(prot, output, len) == 0) { + alias_target = flb_plugin_alias_get(FLB_PLUGIN_OUTPUT, output, len); + if (alias_target != NULL && + strlen(alias_target) == strlen(prot) && + strcasecmp(prot, alias_target) == 0) { return 1; } @@ -676,6 +682,8 @@ struct flb_output_instance *flb_output_new(struct flb_config *config, { int ret = -1; int flags = 0; + const char *output_name; + char *output_uri; struct mk_list *head; struct flb_output_plugin *plugin; struct flb_output_instance *instance = NULL; @@ -684,9 +692,12 @@ struct flb_output_instance *flb_output_new(struct flb_config *config, return NULL; } + output_name = output; + output_uri = NULL; + mk_list_foreach(head, &config->out_plugins) { plugin = mk_list_entry(head, struct flb_output_plugin, _head); - if (!check_protocol(plugin->name, output)) { + if (!check_protocol(plugin->name, output_name)) { plugin = NULL; continue; } @@ -818,12 +829,45 @@ struct flb_output_instance *flb_output_new(struct flb_config *config, # endif #endif + output_uri = flb_plugin_alias_rewrite(FLB_PLUGIN_OUTPUT, output_name); + if (output_uri == FLB_PLUGIN_ALIAS_ERR) { + if ((instance->flags & FLB_OUTPUT_SYNCHRONOUS) && + instance->singleplex_queue != NULL) { + flb_task_queue_destroy(instance->singleplex_queue); + } + if (instance->callback != NULL) { + flb_callback_destroy(instance->callback); + } + if (plugin->type != FLB_OUTPUT_PLUGIN_CORE && + instance->context != NULL) { + flb_free(instance->context); + } + flb_free(instance->http_server_config); + flb_free(instance); + return NULL; + } + else if (output_uri != NULL) { + output_name = output_uri; + } + if (plugin->flags & FLB_OUTPUT_NET) { - ret = flb_net_host_set(plugin->name, &instance->host, output); + ret = flb_net_host_set(plugin->name, &instance->host, output_name); + if (output_uri != NULL) { + flb_free(output_uri); + } + if (ret != 0) { - if (instance->flags & FLB_OUTPUT_SYNCHRONOUS) { + if ((instance->flags & FLB_OUTPUT_SYNCHRONOUS) && + instance->singleplex_queue != NULL) { flb_task_queue_destroy(instance->singleplex_queue); } + if (instance->callback != NULL) { + flb_callback_destroy(instance->callback); + } + if (plugin->type != FLB_OUTPUT_PLUGIN_CORE && + instance->context != NULL) { + flb_free(instance->context); + } flb_free(instance->http_server_config); flb_free(instance); return NULL; diff --git a/src/flb_plugin_alias.c b/src/flb_plugin_alias.c new file mode 100644 index 00000000000..f32c4ec14f8 --- /dev/null +++ b/src/flb_plugin_alias.c @@ -0,0 +1,180 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +/* Fluent Bit + * ========== + * Copyright (C) 2015-2026 The Fluent Bit Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * 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. + */ + +#include +#include + +#include +#include +#include +#include +#include + +/* + * Table that maps user-facing aliases to plugin short names. + * + * Keep this table focused on backwards/forwards compatibility names where the + * historical short name is still used internally by the plugin implementation. + */ +static struct flb_plugin_alias_entry plugin_aliases[] = { + { + FLB_PLUGIN_OUTPUT, + "elasticsearch", + "es" + }, + { + 0, + NULL, + NULL + } +}; + +static const struct flb_plugin_alias_entry *custom_plugin_aliases = NULL; +static pthread_mutex_t custom_plugin_aliases_lock = PTHREAD_MUTEX_INITIALIZER; + +static size_t protocol_part_length(const char *plugin_reference) +{ + char *separator; + + separator = strstr(plugin_reference, "://"); + if (separator != NULL && separator != plugin_reference) { + return (size_t) (separator - plugin_reference); + } + + return strlen(plugin_reference); +} + +const char *flb_plugin_alias_get(int plugin_type, const char *alias_name, + size_t alias_name_length) +{ + int index; + const struct flb_plugin_alias_entry *entry; + const struct flb_plugin_alias_entry *aliases; + + if (alias_name == NULL || alias_name_length == 0) { + return NULL; + } + + pthread_mutex_lock(&custom_plugin_aliases_lock); + aliases = custom_plugin_aliases; + if (aliases != NULL) { + for (index = 0; aliases[index].alias_name != NULL; index++) { + entry = &aliases[index]; + + if (entry->plugin_type != plugin_type) { + continue; + } + + if (strlen(entry->alias_name) != alias_name_length) { + continue; + } + + if (strncasecmp(entry->alias_name, alias_name, alias_name_length) == 0) { + pthread_mutex_unlock(&custom_plugin_aliases_lock); + return entry->plugin_name; + } + } + } + pthread_mutex_unlock(&custom_plugin_aliases_lock); + + for (index = 0; plugin_aliases[index].alias_name != NULL; index++) { + entry = &plugin_aliases[index]; + + if (entry->plugin_type != plugin_type) { + continue; + } + + if (strlen(entry->alias_name) != alias_name_length) { + continue; + } + + if (strncasecmp(entry->alias_name, alias_name, alias_name_length) == 0) { + return entry->plugin_name; + } + } + + return NULL; +} + +void flb_plugin_alias_set_custom_entries( + const struct flb_plugin_alias_entry *entries) +{ + pthread_mutex_lock(&custom_plugin_aliases_lock); + custom_plugin_aliases = entries; + pthread_mutex_unlock(&custom_plugin_aliases_lock); +} + +void flb_plugin_alias_reset_custom_entries(void) +{ + pthread_mutex_lock(&custom_plugin_aliases_lock); + custom_plugin_aliases = NULL; + pthread_mutex_unlock(&custom_plugin_aliases_lock); +} + +char *flb_plugin_alias_rewrite(int plugin_type, const char *plugin_reference) +{ + int ret; + size_t reference_length; + size_t protocol_length; + size_t plugin_name_length; + char *rewritten_reference; + const char *plugin_name; + + if (plugin_reference == NULL) { + return NULL; + } + + protocol_length = protocol_part_length(plugin_reference); + if (protocol_length == 0) { + return NULL; + } + + plugin_name = flb_plugin_alias_get(plugin_type, plugin_reference, + protocol_length); + if (plugin_name == NULL) { + return NULL; + } + + plugin_name_length = strlen(plugin_name); + + if (plugin_name_length == protocol_length && + strncasecmp(plugin_name, plugin_reference, protocol_length) == 0) { + return NULL; + } + + reference_length = strlen(plugin_reference); + rewritten_reference = flb_calloc(1, reference_length - protocol_length + + plugin_name_length + 1); + if (rewritten_reference == NULL) { + flb_errno(); + return FLB_PLUGIN_ALIAS_ERR; + } + + memcpy(rewritten_reference, plugin_name, plugin_name_length); + + ret = snprintf(rewritten_reference + plugin_name_length, + reference_length - protocol_length + 1, + "%s", plugin_reference + protocol_length); + if (ret < 0) { + flb_free(rewritten_reference); + return FLB_PLUGIN_ALIAS_ERR; + } + + return rewritten_reference; +} diff --git a/src/flb_processor.c b/src/flb_processor.c index 5de6a4e9780..6e119ac81c8 100644 --- a/src/flb_processor.c +++ b/src/flb_processor.c @@ -35,6 +35,7 @@ #include #include #include +#include #include struct flb_config_map processor_global_properties[] = { @@ -625,6 +626,19 @@ struct flb_processor_unit *flb_processor_unit_create(struct flb_processor *proc, struct flb_config *config = proc->config; struct flb_processor_unit *pu = NULL; struct flb_processor_instance *processor_instance; + char *rewritten_unit_name; + const char *effective_unit_name; + + rewritten_unit_name = flb_plugin_alias_rewrite(FLB_PLUGIN_PROCESSOR, unit_name); + if (rewritten_unit_name == FLB_PLUGIN_ALIAS_ERR) { + return NULL; + } + if (rewritten_unit_name != NULL) { + effective_unit_name = rewritten_unit_name; + } + else { + effective_unit_name = unit_name; + } /* * Looking the processor unit by using it's name and type, the first list we @@ -641,7 +655,7 @@ struct flb_processor_unit *flb_processor_unit_create(struct flb_processor *proc, /* skip filters which don't handle the required type */ if ((event_type & filter_event_type) != 0) { - if (strcmp(f->name, unit_name) == 0) { + if (strcmp(f->name, effective_unit_name) == 0) { break; } } @@ -654,16 +668,18 @@ struct flb_processor_unit *flb_processor_unit_create(struct flb_processor *proc, if (!pu) { flb_errno(); + flb_free(rewritten_unit_name); return NULL; } pu->parent = proc; pu->event_type = event_type; - pu->name = flb_sds_create(unit_name); + pu->name = flb_sds_create(effective_unit_name); pu->condition = NULL; if (!pu->name) { flb_free(pu); + flb_free(rewritten_unit_name); return NULL; } mk_list_init(&pu->unused_list); @@ -673,19 +689,20 @@ struct flb_processor_unit *flb_processor_unit_create(struct flb_processor *proc, if (result != 0) { flb_sds_destroy(pu->name); flb_free(pu); - + flb_free(rewritten_unit_name); return NULL; } /* If we matched a pipeline filter, create the speacial processing unit for it */ if (f) { /* create an instance of the filter */ - f_ins = flb_filter_new(config, unit_name, NULL); + f_ins = flb_filter_new(config, effective_unit_name, NULL); if (!f_ins) { pthread_mutex_destroy(&pu->lock); flb_sds_destroy(pu->name); flb_free(pu); + flb_free(rewritten_unit_name); return NULL; } @@ -701,6 +718,7 @@ struct flb_processor_unit *flb_processor_unit_create(struct flb_processor *proc, pthread_mutex_destroy(&pu->lock); flb_sds_destroy(pu->name); flb_free(pu); + flb_free(rewritten_unit_name); return NULL; } @@ -725,7 +743,7 @@ struct flb_processor_unit *flb_processor_unit_create(struct flb_processor *proc, processor_instance = flb_processor_instance_create(config, pu, pu->event_type, - unit_name, NULL); + (char *) effective_unit_name, NULL); if (processor_instance == NULL) { flb_error("[processor] error creating processor '%s': plugin doesn't exist or failed to initialize", unit_name); @@ -733,6 +751,7 @@ struct flb_processor_unit *flb_processor_unit_create(struct flb_processor *proc, pthread_mutex_destroy(&pu->lock); flb_sds_destroy(pu->name); flb_free(pu); + flb_free(rewritten_unit_name); return NULL; } @@ -757,6 +776,7 @@ struct flb_processor_unit *flb_processor_unit_create(struct flb_processor *proc, pu->stage = proc->stage_count; proc->stage_count++; + flb_free(rewritten_unit_name); return pu; } diff --git a/tests/internal/CMakeLists.txt b/tests/internal/CMakeLists.txt index 9f01fc93b26..9f4543764fc 100644 --- a/tests/internal/CMakeLists.txt +++ b/tests/internal/CMakeLists.txt @@ -53,6 +53,7 @@ set(UNIT_TESTS_FILES endianness.c task_map.c strptime.c + plugin_alias.c storage_inherit.c unicode.c opentelemetry.c diff --git a/tests/internal/plugin_alias.c b/tests/internal/plugin_alias.c new file mode 100644 index 00000000000..31b2979757a --- /dev/null +++ b/tests/internal/plugin_alias.c @@ -0,0 +1,168 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +/* Fluent Bit + * ========== + * Copyright (C) 2015-2026 The Fluent Bit Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "flb_tests_internal.h" + +static struct flb_plugin_alias_entry custom_aliases[] = { + { FLB_PLUGIN_INPUT, "tailing", "tail" }, + { FLB_PLUGIN_FILTER, "grepper", "grep" }, + { FLB_PLUGIN_PROCESSOR, "countering", "content_modifier" }, + { FLB_PLUGIN_OUTPUT, "elasticsearch", "es_custom" }, + { 0, NULL, NULL } +}; + +void plugin_alias_lookup_test() +{ + const char *alias_target; + + alias_target = flb_plugin_alias_get(FLB_PLUGIN_OUTPUT, "elasticsearch", + strlen("elasticsearch")); + if (!TEST_CHECK(alias_target != NULL)) { + TEST_MSG("output plugin alias was not resolved"); + return; + } + + if (!TEST_CHECK(strcmp(alias_target, "es") == 0)) { + TEST_MSG("unexpected alias target: %s", alias_target); + } +} + +void plugin_alias_custom_map_test() +{ + const char *alias_target; + + flb_plugin_alias_set_custom_entries(custom_aliases); + + alias_target = flb_plugin_alias_get(FLB_PLUGIN_INPUT, "tailing", + strlen("tailing")); + TEST_CHECK(alias_target != NULL); + TEST_CHECK(strcmp(alias_target, "tail") == 0); + + alias_target = flb_plugin_alias_get(FLB_PLUGIN_FILTER, "grepper", + strlen("grepper")); + TEST_CHECK(alias_target != NULL); + TEST_CHECK(strcmp(alias_target, "grep") == 0); + + alias_target = flb_plugin_alias_get(FLB_PLUGIN_OUTPUT, "elasticsearch", + strlen("elasticsearch")); + TEST_CHECK(alias_target != NULL); + TEST_CHECK(strcmp(alias_target, "es_custom") == 0); + + flb_plugin_alias_reset_custom_entries(); + + alias_target = flb_plugin_alias_get(FLB_PLUGIN_OUTPUT, "elasticsearch", + strlen("elasticsearch")); + TEST_CHECK(alias_target != NULL); + TEST_CHECK(strcmp(alias_target, "es") == 0); +} + +void plugin_alias_rewrite_test() +{ + char *rewritten_name; + + rewritten_name = flb_plugin_alias_rewrite(FLB_PLUGIN_OUTPUT, + "elasticsearch://127.0.0.1:9200"); + if (!TEST_CHECK(rewritten_name != FLB_PLUGIN_ALIAS_ERR)) { + TEST_MSG("error while rewriting output plugin alias"); + return; + } + if (!TEST_CHECK(rewritten_name != NULL)) { + TEST_MSG("could not rewrite output plugin alias"); + return; + } + + if (!TEST_CHECK(strcmp(rewritten_name, "es://127.0.0.1:9200") == 0)) { + TEST_MSG("unexpected rewritten output plugin name: %s", rewritten_name); + } + + flb_free(rewritten_name); +} + +void network_alias_address_parse_test() +{ + int ret; + struct flb_net_host host; + + ret = flb_net_host_set("es", &host, "elasticsearch://127.0.0.1:9200/path"); + if (!TEST_CHECK(ret == 0)) { + TEST_MSG("could not parse alias output address"); + return; + } + + if (!TEST_CHECK(strcmp(host.name, "127.0.0.1") == 0)) { + TEST_MSG("unexpected host name parsed from alias output address: %s", + host.name); + } + + if (!TEST_CHECK(host.port == 9200)) { + TEST_MSG("unexpected host port parsed from alias output address: %d", + host.port); + } + + flb_sds_destroy(host.name); + flb_sds_destroy(host.listen); + flb_uri_destroy(host.uri); + flb_sds_destroy(host.address); +} + +void output_alias_instantiation_test() +{ + struct flb_config *config; + struct flb_output_instance *instance; + + config = flb_config_init(); + if (!TEST_CHECK(config != NULL)) { + TEST_MSG("could not initialize config context"); + return; + } + + instance = flb_output_new(config, "elasticsearch", NULL, FLB_TRUE); + if (!TEST_CHECK(instance != NULL)) { + TEST_MSG("could not instantiate aliased output plugin"); + flb_config_exit(config); + return; + } + + if (!TEST_CHECK(strcmp(instance->p->name, "es") == 0)) { + TEST_MSG("unexpected output plugin instantiated for alias: %s", + instance->p->name); + } + + flb_output_instance_destroy(instance); + flb_config_exit(config); +} + +TEST_LIST = { + { "plugin_alias_lookup_test", plugin_alias_lookup_test }, + { "plugin_alias_custom_map_test", plugin_alias_custom_map_test }, + { "plugin_alias_rewrite_test", plugin_alias_rewrite_test }, + { "network_alias_address_parse_test", network_alias_address_parse_test }, + { "output_alias_instantiation_test", output_alias_instantiation_test }, + { 0 } +};