/
githubmirror
/
fwupd
Обзор
Документация
Войти
/
githubmirror
/
fwupd
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/fu-engine-gtypes-test.c
400 строк
14 KB
Peter Hutterer
Drop fu_memory_input_stream_new() from the API
06 авг 2026, 10:39
06 авг 2026, 10:39
ba50054
Код
Авторство
О чём код?
/* * Copyright 2015 Richard Hughes <richard@hughsie.com> * * SPDX-License-Identifier: LGPL-2.1-or-later */ #include "config.h" #include "fu-context-private.h" #include "fu-device-private.h" #include "fu-drm-device-private.h" #include "fu-engine.h" #include "fu-firmware-private.h" #include "fu-input-stream.h" #include "fu-plugin-private.h" #include "fu-security-attrs-private.h" static void fu_engine_plugin_device_gtype(FuContext *ctx, GType gtype, gboolean is_fake) { GType proxy_gtype; gboolean ret; g_autofree gchar *str = NULL; g_autoptr(FuDevice) device = NULL; g_autoptr(FuDevice) device2 = NULL; g_autoptr(FuDeviceLocker) locker = NULL; g_autoptr(FuFirmware) firmware = NULL; g_autoptr(FuProgress) progress_tmp = fu_progress_new(G_STRLOC); g_autoptr(FuSecurityAttrs) attrs = fu_security_attrs_new(); g_autoptr(FwupdJsonObject) json_obj = fwupd_json_object_new(); g_autoptr(GError) error = NULL; g_autoptr(GHashTable) metadata_post = NULL; g_autoptr(GHashTable) metadata_pre = NULL; g_autoptr(GBytes) data = g_bytes_new(NULL, 0); g_autoptr(FuInputStream) stream = fu_memory_input_stream_new_from_bytes(data); g_debug("loading %s", g_type_name(gtype)); device = g_object_new(gtype, "context", ctx, "physical-id", "/sys", NULL); g_assert_nonnull(device); fu_device_set_plugin(device, "test"); fu_device_add_flag(device, FWUPD_DEVICE_FLAG_EMULATED); fu_device_set_remove_delay(device, FU_DEVICE_REMOVE_DELAY_RE_ENUMERATE); if (is_fake) fu_device_add_private_flag(device, FU_DEVICE_PRIVATE_FLAG_IS_FAKE); /* version convert */ if (fu_device_get_version_format(device) != FWUPD_VERSION_FORMAT_UNKNOWN) fu_device_set_version_raw(device, 0); /* progress steps */ fu_device_set_progress(device, progress_tmp); /* report metadata */ metadata_pre = fu_device_report_metadata_pre(device); if (metadata_pre != NULL) g_debug("got %u metadata items", g_hash_table_size(metadata_pre)); metadata_post = fu_device_report_metadata_post(device); if (metadata_post != NULL) g_debug("got %u metadata items", g_hash_table_size(metadata_post)); /* security attrs */ fu_device_add_security_attrs(device, attrs); /* quirk kvs */ ret = fu_device_set_quirk_kv(device, "NoGoingTo", "Exist", FU_CONTEXT_QUIRK_SOURCE_FALLBACK, &error); g_assert_error(error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED); g_assert_false(ret); /* to string */ str = fu_device_to_string(device); g_assert_nonnull(str); /* proxy required */ proxy_gtype = fu_device_get_proxy_gtype(device); if (proxy_gtype != G_TYPE_INVALID && G_TYPE_FUNDAMENTAL(proxy_gtype) == G_TYPE_OBJECT) { g_autoptr(FuDevice) proxy = g_object_new(proxy_gtype, "context", ctx, "physical-id", "/sys", NULL); fu_device_add_flag(proxy, FWUPD_DEVICE_FLAG_EMULATED); if (is_fake) fu_device_add_private_flag(proxy, FU_DEVICE_PRIVATE_FLAG_IS_FAKE); fu_device_add_private_flag(device, FU_DEVICE_PRIVATE_FLAG_REFCOUNTED_PROXY); fu_device_set_proxy(device, proxy); } /* ->probe() and ->setup */ locker = fu_device_locker_new(device, NULL); if (locker != NULL) g_debug("did ->probe() and ->setup()!"); /* ->prepare(), ->attach(), ->detach, ->cleanup */ if (fu_device_prepare(device, progress_tmp, FWUPD_INSTALL_FLAG_FORCE, NULL)) g_debug("did ->prepare()"); if (fu_device_attach_full(device, progress_tmp, NULL)) g_debug("did ->attach()"); if (fu_device_poll(device, NULL)) g_debug("did ->poll()"); if (fu_device_detach_full(device, progress_tmp, NULL)) g_debug("did ->detach()"); if (fu_device_cleanup(device, progress_tmp, FWUPD_INSTALL_FLAG_FORCE, NULL)) g_debug("did ->cleanup()"); /* ->prepare_firmware() */ firmware = fu_device_prepare_firmware(device, stream, progress_tmp, FU_FIRMWARE_PARSE_FLAG_NONE, NULL); if (firmware == NULL) { GType firmware_gtype = fu_device_get_firmware_gtype(device); if (firmware_gtype != G_TYPE_INVALID) firmware = g_object_new(firmware_gtype, NULL); } if (firmware != NULL) { if (fu_device_write_firmware(device, firmware, progress_tmp, FWUPD_INSTALL_FLAG_FORCE, NULL)) { g_debug("did ->write_firmware()!"); } } /* incorporate */ device2 = g_object_new(gtype, "context", ctx, NULL); fu_device_incorporate(device2, device, FU_DEVICE_INCORPORATE_FLAG_ALL); /* roundtrip to JSON */ fu_device_add_json(device2, json_obj, FWUPD_CODEC_FLAG_TRUSTED); if (fu_device_from_json(device2, json_obj, NULL)) g_debug("did ->from_json()"); } static void fu_engine_plugin_firmware_gtype(GHashTable *gtype_map, GType gtype) { gboolean ret; guint n_gtypes = 0; const GType *image_gtypes; g_autoptr(FuFirmware) firmware = NULL; g_autoptr(GBytes) blob = NULL; g_autoptr(GBytes) fw = g_bytes_new_static((const guint8 *)"x", 1); g_autoptr(GError) error = NULL; const gchar *noxml[] = { "FuCsvEntry", "FuFirmware", "FuGenesysUsbhubFirmware", "FuJsonFirmware", NULL, }; /* do not parse the same type more than once */ if (g_hash_table_contains(gtype_map, GINT_TO_POINTER(gtype))) return; g_hash_table_add(gtype_map, GINT_TO_POINTER(gtype)); g_debug("loading %s", g_type_name(gtype)); firmware = g_object_new(gtype, NULL); g_assert_nonnull(firmware); /* check the size max is set */ if (gtype != FU_TYPE_FIRMWARE && !fu_firmware_has_flag(firmware, FU_FIRMWARE_FLAG_IS_ABSTRACT) && fu_firmware_get_size_max(firmware) == FU_FIRMWARE_SIZE_MAX_DEFAULT) g_warning("%s did not set firmware max size", g_type_name(gtype)); /* ensure we have data set even if parsing fails */ fu_firmware_set_bytes(firmware, fw); /* version convert */ if (fu_firmware_get_version_format(firmware) != FWUPD_VERSION_FORMAT_UNKNOWN) fu_firmware_set_version_raw(firmware, 0); /* parse nonsense */ if (gtype != FU_TYPE_FIRMWARE && !fu_firmware_has_flag(firmware, FU_FIRMWARE_FLAG_IS_ABSTRACT) && !fu_firmware_has_flag(firmware, FU_FIRMWARE_FLAG_NO_AUTO_DETECTION)) { ret = fu_firmware_parse_bytes(firmware, fw, 0x0, FU_FIRMWARE_PARSE_FLAG_NO_SEARCH | FU_FIRMWARE_PARSE_FLAG_CACHE_STREAM, NULL); g_assert_false(ret); } /* write */ blob = fu_firmware_write(firmware, NULL); if (blob != NULL && g_bytes_get_size(blob) > 0) g_debug("saved 0x%x bytes", (guint)g_bytes_get_size(blob)); /* export -> build */ if (!g_strv_contains(noxml, g_type_name(gtype))) { g_autofree gchar *xml = fu_firmware_export_to_xml( firmware, FU_FIRMWARE_EXPORT_FLAG_INCLUDE_DEBUG | FU_FIRMWARE_EXPORT_FLAG_ASCII_DATA, NULL); if (xml != NULL) { g_autoptr(FuFirmware) firmware2 = fu_firmware_new_from_xml(xml, &error); g_assert_no_error(error); g_assert_nonnull(firmware2); } } /* check child GType's too */ image_gtypes = fu_firmware_get_image_gtypes(firmware, &n_gtypes); for (guint i = 0; i < n_gtypes; i++) { if (image_gtypes[i] == gtype || image_gtypes[i] == FU_TYPE_FIRMWARE) continue; fu_engine_plugin_firmware_gtype(gtype_map, image_gtypes[i]); } } static void fu_engine_gtypes_func(void) { GPtrArray *plugins; gboolean ret; g_autofree gchar *testdatadir = NULL; g_autoptr(FuContext) ctx = fu_context_new_full(FU_CONTEXT_FLAG_NO_QUIRKS | FU_CONTEXT_FLAG_INHIBIT_VOLUME_MOUNT); g_autoptr(FuDrmDevice) drm_device = g_object_new(FU_TYPE_DRM_DEVICE, NULL); g_autoptr(FuEdid) edid = fu_edid_new(); g_autoptr(FuEngine) engine = fu_engine_new(ctx); g_autoptr(FuProgress) progress = fu_progress_new(G_STRLOC); g_autoptr(FuSecurityAttrs) attrs = fu_security_attrs_new(); g_autoptr(GHashTable) gtype_map = g_hash_table_new(g_direct_hash, g_direct_equal); g_autoptr(GArray) firmware_gtypes = NULL; g_autoptr(GError) error = NULL; g_autoptr(XbSilo) silo_empty = xb_silo_new(); const gchar *external_plugins[] = { "modem-manager", }; /* set up test harness */ testdatadir = g_test_build_filename(G_TEST_DIST, "tests", NULL); fu_context_set_path(ctx, FU_PATH_KIND_SYSCONFDIR_PKG, testdatadir); /* no metadata in daemon */ fu_engine_set_silo(engine, silo_empty); /* load these from the build directory, not the install directory */ if (g_getenv("G_TEST_BUILDDIR") != NULL) { g_autoptr(GPtrArray) external_plugin_dirs = g_ptr_array_new_with_free_func(g_free); g_autofree gchar *external_plugindir = NULL; for (guint i = 0; i < G_N_ELEMENTS(external_plugins); i++) { g_ptr_array_add(external_plugin_dirs, g_test_build_filename(G_TEST_BUILT, "..", "plugins", external_plugins[i], NULL)); } external_plugindir = fu_strjoin(",", external_plugin_dirs); fu_context_set_path(ctx, FU_PATH_KIND_LIBDIR_PKG, external_plugindir); } else { fu_context_set_path(ctx, FU_PATH_KIND_LIBDIR_PKG, FWUPD_LIBDIR_PKG); } /* load all plugins */ ret = fu_engine_load(engine, FU_ENGINE_LOAD_FLAG_BUILTIN_PLUGINS | FU_ENGINE_LOAD_FLAG_HWINFO | FU_ENGINE_LOAD_FLAG_EXTERNAL_PLUGINS | FU_ENGINE_LOAD_FLAG_NO_CACHE, progress, &error); g_assert_no_error(error); g_assert_true(ret); plugins = fu_engine_get_plugins(engine); g_assert_nonnull(plugins); g_assert_cmpint(plugins->len, >, 5); /* start up plugins */ for (guint i = 0; i < plugins->len; i++) { FuPlugin *plugin = g_ptr_array_index(plugins, i); g_autoptr(GError) error_local = NULL; if (!fu_plugin_runner_startup(plugin, progress, &error_local)) g_debug("ignoring: %s", error_local->message); } /* add security attrs where possible */ for (guint i = 0; i < plugins->len; i++) { FuPlugin *plugin = g_ptr_array_index(plugins, i); fu_plugin_runner_add_security_attrs(plugin, attrs); } /* run the post-reboot action */ for (guint i = 0; i < plugins->len; i++) { FuPlugin *plugin = g_ptr_array_index(plugins, i); g_autoptr(FuDevice) device_nop = fu_device_new(ctx); g_autoptr(GError) error_local = NULL; if (!fu_plugin_runner_reboot_cleanup(plugin, device_nop, &error_local)) g_debug("ignoring: %s", error_local->message); } /* run the composite-prepare action */ for (guint i = 0; i < plugins->len; i++) { FuPlugin *plugin = g_ptr_array_index(plugins, i); g_autoptr(FuDevice) device_nop = fu_device_new(ctx); g_autoptr(GError) error_local = NULL; g_autoptr(GPtrArray) devices = g_ptr_array_new(); g_ptr_array_add(devices, device_nop); if (!fu_plugin_runner_composite_prepare(plugin, devices, &error_local)) g_debug("ignoring: %s", error_local->message); } /* run the composite-cleanup action */ for (guint i = 0; i < plugins->len; i++) { FuPlugin *plugin = g_ptr_array_index(plugins, i); g_autoptr(FuDevice) device_nop = fu_device_new(ctx); g_autoptr(GError) error_local = NULL; g_autoptr(GPtrArray) devices = g_ptr_array_new(); g_ptr_array_add(devices, device_nop); if (!fu_plugin_runner_composite_cleanup(plugin, devices, &error_local)) g_debug("ignoring: %s", error_local->message); } /* run the composite-peek-firmware action */ for (guint i = 0; i < plugins->len; i++) { FuPlugin *plugin = g_ptr_array_index(plugins, i); g_autoptr(GBytes) blob = g_bytes_new_static("xxx", 3); g_autoptr(FuDevice) device_nop = fu_device_new(ctx); g_autoptr(FuFirmware) firmware = fu_firmware_new_from_bytes(blob); g_autoptr(GError) error_local = NULL; fu_device_set_plugin(device_nop, "uefi_dbx"); if (!fu_plugin_runner_composite_peek_firmware(plugin, device_nop, firmware, progress, FWUPD_INSTALL_FLAG_NONE, &error_local)) g_debug("ignoring: %s", error_local->message); } /* run the device unlock action */ for (guint i = 0; i < plugins->len; i++) { FuPlugin *plugin = g_ptr_array_index(plugins, i); g_autoptr(FuDevice) device_nop = fu_device_new(ctx); g_autoptr(GError) error_local = NULL; if (!fu_plugin_runner_unlock(plugin, device_nop, &error_local)) g_debug("ignoring: %s", error_local->message); } /* run the backend-device-added action */ for (guint i = 0; i < plugins->len; i++) { FuPlugin *plugin = g_ptr_array_index(plugins, i); GArray *device_gtypes = fu_plugin_get_device_gtypes(plugin); if (device_gtypes == NULL || device_gtypes->len == 0) { g_autoptr(FuDevice) device_nop = fu_device_new(ctx); g_autoptr(GError) error_local = NULL; if (!fu_plugin_runner_backend_device_added(plugin, device_nop, progress, &error_local)) g_debug("ignoring: %s", error_local->message); } } /* register a DRM device as some plugins use these for quirks */ fu_edid_set_pnp_id(edid, "PNP"); fu_edid_set_eisa_id(edid, "IBM"); fu_edid_set_product_name(edid, "Display"); fu_edid_set_serial_number(edid, "123456"); fu_edid_set_product_code(edid, 0x1234); fu_drm_device_set_edid(drm_device, edid); for (guint i = 0; i < plugins->len; i++) { FuPlugin *plugin = g_ptr_array_index(plugins, i); fu_plugin_runner_device_register(plugin, FU_DEVICE(drm_device)); } /* create each custom device with a context only */ for (guint i = 0; i < plugins->len; i++) { FuPlugin *plugin = g_ptr_array_index(plugins, i); GArray *device_gtypes = fu_plugin_get_device_gtypes(plugin); for (guint j = 0; device_gtypes != NULL && j < device_gtypes->len; j++) { GType gtype = g_array_index(device_gtypes, GType, j); fu_engine_plugin_device_gtype(ctx, gtype, TRUE); fu_engine_plugin_device_gtype(ctx, gtype, FALSE); } } /* create each firmware */ firmware_gtypes = fu_context_get_firmware_gtypes(ctx); for (guint j = 0; j < firmware_gtypes->len; j++) { GType gtype = g_array_index(firmware_gtypes, GType, j); fu_engine_plugin_firmware_gtype(gtype_map, gtype); } } int main(int argc, char **argv) { g_test_init(&argc, &argv, NULL); g_test_add_func("/fwupd/engine/gtypes", fu_engine_gtypes_func); return g_test_run(); }