summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel P. Berrangé <berrange@redhat.com>2021-11-24 18:27:53 +0000
committerDaniel P. Berrangé <berrange@redhat.com>2022-02-04 14:14:49 +0000
commit0d7a8e9682fe3e855fa3ec8aac0264101521cf7f (patch)
treef41d8ba6ac1c9c451125cab018a735d3799d8b7a
parentc0ba8e5d0b74625f1236c904d951f4bd6221818e (diff)
downloadlibosinfo-0d7a8e9682fe3e855fa3ec8aac0264101521cf7f.tar.gz
osinfo: add API for resolving multiple tree matches
A provided tree object might match multiple entries from the database. Add an API that allows for this possibility to let applications decide how to handle it. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
-rw-r--r--osinfo/libosinfo.syms1
-rw-r--r--osinfo/osinfo_db.c36
-rw-r--r--osinfo/osinfo_db.h2
-rw-r--r--tests/test-db.c91
4 files changed, 130 insertions, 0 deletions
diff --git a/osinfo/libosinfo.syms b/osinfo/libosinfo.syms
index 5c4221d..ae5fee3 100644
--- a/osinfo/libosinfo.syms
+++ b/osinfo/libosinfo.syms
@@ -640,6 +640,7 @@ LIBOSINFO_1.10.0 {
global:
osinfo_db_identify_medialist;
+ osinfo_db_identify_treelist;
osinfo_media_matches;
osinfo_os_get_complete_firmware_list;
osinfo_tree_matches;
diff --git a/osinfo/osinfo_db.c b/osinfo/osinfo_db.c
index 7b5ea9b..074726a 100644
--- a/osinfo/osinfo_db.c
+++ b/osinfo/osinfo_db.c
@@ -1086,6 +1086,13 @@ static void fill_tree(OsinfoDb *db, OsinfoTree *tree,
* the tree could be identified, its OsinfoEntify::id and OsinfoMedia::os
* properties will be set.
*
+ * The match for @tree in @db is not guaranteed to be unique and
+ * this method will only return the first match found. The order
+ * in which matches are identified is not guaranteed, so when there
+ * are multiple matches, the returned match may vary over time.
+ * Applications are recommended to use the #osinfo_db_identify_all_tree
+ * method instead to receive all matched tree.
+ *
* Returns: TRUE if @tree was found in @db, FALSE otherwise
*
* Since: 1.6.0
@@ -1111,6 +1118,35 @@ gboolean osinfo_db_identify_tree(OsinfoDb *db,
return TRUE;
}
+/**
+ * osinfo_db_identify_treelist:
+ * @db: an #OsinfoDb database
+ * @tree: the installation tree data
+ *
+ * Try to match a newly created @tree with a tree description from @db.
+ * The return list will contain any #OsinfoTree instances from @db that
+ * matched @tree. Usuaully there will only be one match returned, but
+ * applications should be prepared to deal with multiple matches. The
+ * returned #OsinfoTree instances will have their OsinfoEntify::id and
+ * OsinfoTree::os properties will be set, while @tree is left unmodified.
+ *
+ * Returns: (transfer full): a list containing any matches for @tree found in @db
+ *
+ * Since: 1.10.0
+ */
+OsinfoTreeList *osinfo_db_identify_treelist(OsinfoDb *db, OsinfoTree *tree)
+{
+ OsinfoTreeList *matched_tree = osinfo_treelist_new();
+
+ g_return_val_if_fail(OSINFO_IS_TREE(tree), FALSE);
+ g_return_val_if_fail(OSINFO_IS_DB(db), FALSE);
+
+ osinfo_db_guess_os_from_tree_internal(db, tree, matched_tree,
+ FALSE, NULL);
+
+ return matched_tree;
+}
+
struct osinfo_db_populate_values_args {
GHashTable *values;
const gchar *property;
diff --git a/osinfo/osinfo_db.h b/osinfo/osinfo_db.h
index aee2e64..7289cfb 100644
--- a/osinfo/osinfo_db.h
+++ b/osinfo/osinfo_db.h
@@ -80,6 +80,8 @@ OsinfoOs *osinfo_db_guess_os_from_tree(OsinfoDb *db,
OsinfoTree **matched_tree);
gboolean osinfo_db_identify_tree(OsinfoDb *db,
OsinfoTree *tree);
+OsinfoTreeList *osinfo_db_identify_treelist(OsinfoDb *db,
+ OsinfoTree *tree);
// Get me all unique values for property "vendor" among operating systems
GList *osinfo_db_unique_values_for_property_in_os(OsinfoDb *db, const gchar *propName);
diff --git a/tests/test-db.c b/tests/test-db.c
index ac5bfed..d5f48af 100644
--- a/tests/test-db.c
+++ b/tests/test-db.c
@@ -789,6 +789,96 @@ test_identify_tree(void)
}
+static void
+test_identify_all_tree(void)
+{
+ OsinfoLoader *loader = osinfo_loader_new();
+ OsinfoDb *db;
+ OsinfoTree *tree, *newtree;
+ OsinfoTreeList *treelist;
+ gboolean seenV6, seenV7, seenFallback;
+ GError *error = NULL;
+ int i;
+
+ osinfo_loader_process_path(loader, SRCDIR "/tests/dbdata", &error);
+ g_assert_no_error(error);
+ db = osinfo_loader_get_db(loader);
+
+ /* Matching against an "all" architecture" */
+ tree = create_tree("x86_64", NULL);
+ treelist = osinfo_db_identify_treelist(db, tree);
+ g_assert_cmpint(osinfo_list_get_length(OSINFO_LIST(treelist)), ==, 1);
+ newtree = OSINFO_TREE(osinfo_list_get_nth(OSINFO_LIST(treelist), 0));
+ g_assert_cmpstr(osinfo_tree_get_architecture(newtree), ==, "all");
+ g_object_unref(treelist);
+ g_object_unref(tree);
+
+ /* Matching against a known architecture, which has to have precedence */
+ tree = create_tree("i686", "i686");
+ treelist = osinfo_db_identify_treelist(db, tree);
+ g_assert_cmpint(osinfo_list_get_length(OSINFO_LIST(treelist)), ==, 1);
+ newtree = OSINFO_TREE(osinfo_list_get_nth(OSINFO_LIST(treelist), 0));
+ g_assert_cmpstr(osinfo_tree_get_architecture(newtree), ==, "i686");
+ g_object_unref(treelist);
+ g_object_unref(tree);
+
+ /* Matching against a known architecture, which has to have precedence */
+ tree = create_tree(NULL, "i686");
+ treelist = osinfo_db_identify_treelist(db, tree);
+ g_assert_cmpint(osinfo_list_get_length(OSINFO_LIST(treelist)), ==, 1);
+ newtree = OSINFO_TREE(osinfo_list_get_nth(OSINFO_LIST(treelist), 0));
+ g_assert_cmpstr(osinfo_tree_get_architecture(newtree), ==, "i686");
+ g_object_unref(treelist);
+ g_object_unref(tree);
+
+ /* Should not match a tree tagged with different arch, even
+ * if treeinfo matches, but can match fallback arch */
+ seenV6 = seenV7 = seenFallback = FALSE;
+ tree = create_tree("armv7hl", "arm");
+ treelist = osinfo_db_identify_treelist(db, tree);
+ g_assert_cmpint(osinfo_list_get_length(OSINFO_LIST(treelist)), ==, 2);
+ for (i = 0; i < 2; i++) {
+ newtree = OSINFO_TREE(osinfo_list_get_nth(OSINFO_LIST(treelist), i));
+ if (osinfo_tree_get_url(newtree) == NULL) {
+ g_assert_false(seenFallback);
+ seenFallback = TRUE;
+ } else if (g_str_equal(osinfo_tree_get_url(newtree), "http://libosinfo.org/tree/v6")) {
+ g_assert_false(seenV6);
+ seenV6 = TRUE;
+ } else if (g_str_equal(osinfo_tree_get_url(newtree), "http://libosinfo.org/tree/v7")) {
+ g_assert_false(seenV7);
+ seenV7 = TRUE;
+ }
+ }
+ g_assert(!seenV6 && seenV7 && seenFallback);
+ g_object_unref(treelist);
+ g_object_unref(tree);
+
+ tree = create_tree("armv6", "arm");
+ treelist = osinfo_db_identify_treelist(db, tree);
+ g_assert_cmpint(osinfo_list_get_length(OSINFO_LIST(treelist)), ==, 2);
+ seenV6 = seenV7 = seenFallback = FALSE;
+ for (i = 0; i < 2; i++) {
+ newtree = OSINFO_TREE(osinfo_list_get_nth(OSINFO_LIST(treelist), i));
+ if (osinfo_tree_get_url(newtree) == NULL) {
+ g_assert_false(seenFallback);
+ seenFallback = TRUE;
+ } else if (g_str_equal(osinfo_tree_get_url(newtree), "http://libosinfo.org/tree/v6")) {
+ g_assert_false(seenV6);
+ seenV6 = TRUE;
+ } else if (g_str_equal(osinfo_tree_get_url(newtree), "http://libosinfo.org/tree/v7")) {
+ g_assert_false(seenV7);
+ seenV7 = TRUE;
+ }
+ }
+ g_assert(seenV6 && !seenV7 && seenFallback);
+ g_object_unref(treelist);
+ g_object_unref(tree);
+
+ g_object_unref(loader);
+}
+
+
int
main(int argc, char *argv[])
{
@@ -805,6 +895,7 @@ main(int argc, char *argv[])
g_test_add_func("/db/identify_media", test_identify_media);
g_test_add_func("/db/identify_all_media", test_identify_all_media);
g_test_add_func("/db/identify_tree", test_identify_tree);
+ g_test_add_func("/db/identify_all_tree", test_identify_all_tree);
/* Upfront so we don't confuse valgrind */
osinfo_entity_get_type();