Move secret_service_get_secrets() to secret_item_load_secrets()

* And cache the secrets on the items instead of returning
   them in a GHashtable
This commit is contained in:
Stef Walter 2012-07-05 17:11:58 +02:00
parent ba7fe4fe8c
commit 012ed7d620
8 changed files with 363 additions and 361 deletions

View File

@ -65,6 +65,9 @@ secret_item_get_secret
secret_item_load_secret
secret_item_load_secret_finish
secret_item_load_secret_sync
secret_item_load_secrets
secret_item_load_secrets_finish
secret_item_load_secrets_sync
secret_item_set_secret
secret_item_set_secret_finish
secret_item_set_secret_sync
@ -186,9 +189,6 @@ secret_service_ensure_collections_sync
secret_service_search
secret_service_search_finish
secret_service_search_sync
secret_service_get_secrets
secret_service_get_secrets_finish
secret_service_get_secrets_sync
secret_service_lock
secret_service_lock_finish
secret_service_lock_sync

View File

@ -1356,6 +1356,237 @@ secret_item_load_secret_sync (SecretItem *self,
return result;
}
typedef struct {
SecretService *service;
GCancellable *cancellable;
GVariant *in;
GHashTable *items;
} LoadsClosure;
static void
loads_closure_free (gpointer data)
{
LoadsClosure *loads = data;
if (loads->in)
g_variant_unref (loads->in);
if (loads->service)
g_object_unref (loads->service);
g_clear_object (&loads->cancellable);
g_slice_free (LoadsClosure, loads);
}
static void
on_get_secrets_complete (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
LoadsClosure *loads = g_simple_async_result_get_op_res_gpointer (async);
GHashTable *with_paths;
GError *error = NULL;
GHashTableIter iter;
const gchar *path;
SecretValue *value;
SecretItem *item;
GVariant *retval;
retval = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), result, &error);
if (retval != NULL) {
with_paths = _secret_service_decode_get_secrets_all (loads->service, retval);
g_return_if_fail (with_paths != NULL);
g_hash_table_iter_init (&iter, with_paths);
while (g_hash_table_iter_next (&iter, (gpointer *)&path, (gpointer *)&value)) {
item = g_hash_table_lookup (loads->items, path);
if (item != NULL)
_secret_item_set_cached_secret (item, value);
}
g_hash_table_unref (with_paths);
g_variant_unref (retval);
}
if (error != NULL)
g_simple_async_result_take_error (async, error);
g_simple_async_result_complete (async);
g_object_unref (async);
}
static void
on_loads_secrets_session (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
LoadsClosure *loads = g_simple_async_result_get_op_res_gpointer (async);
GError *error = NULL;
const gchar *session;
session = secret_service_ensure_session_finish (SECRET_SERVICE (source),
result, &error);
if (error != NULL) {
g_simple_async_result_take_error (async, error);
g_simple_async_result_complete (async);
} else {
g_dbus_proxy_call (G_DBUS_PROXY (source), "GetSecrets",
g_variant_new ("(@aoo)", loads->in, session),
G_DBUS_CALL_FLAGS_NO_AUTO_START, -1,
loads->cancellable, on_get_secrets_complete,
g_object_ref (async));
}
g_object_unref (async);
}
/**
* secret_item_load_secrets:
* @items: (element-type Secret.Item): the items to retrieve secrets for
* @cancellable: optional cancellation object
* @callback: called when the operation completes
* @user_data: data to pass to the callback
*
* Load the secret values for an secret items stored in the service.
*
* The @items must all have the same SecretItem::service property.
*
* This function returns immediately and completes asynchronously.
*/
void
secret_item_load_secrets (GList *items,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
GSimpleAsyncResult *async;
LoadsClosure *loads;
GPtrArray *paths;
const gchar *path;
GList *l;
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
for (l = items; l != NULL; l = g_list_next (l))
g_return_if_fail (SECRET_IS_ITEM (l->data));
async = g_simple_async_result_new (NULL, callback, user_data,
secret_item_load_secrets);
loads = g_slice_new0 (LoadsClosure);
loads->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
loads->items = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, g_object_unref);
paths = g_ptr_array_new ();
for (l = items; l != NULL; l = g_list_next (l)) {
if (secret_item_get_locked (l->data))
continue;
if (loads->service == NULL) {
loads->service = secret_item_get_service (l->data);
if (loads->service)
g_object_ref (loads->service);
}
path = g_dbus_proxy_get_object_path (l->data);
g_hash_table_insert (loads->items, g_strdup (path), g_object_ref (l->data));
g_ptr_array_add (paths, (gpointer)path);
}
loads->in = g_variant_new_objv ((const gchar * const *)paths->pdata, paths->len);
g_variant_ref_sink (loads->in);
g_ptr_array_free (paths, TRUE);
g_simple_async_result_set_op_res_gpointer (async, loads, loads_closure_free);
if (loads->service) {
secret_service_ensure_session (loads->service, cancellable,
on_loads_secrets_session,
g_object_ref (async));
} else {
g_simple_async_result_complete_in_idle (async);
}
g_object_unref (async);
}
/**
* secret_item_load_secrets_finish:
* @result: asynchronous result passed to callback
* @error: location to place an error on failure
*
* Complete asynchronous operation to load the secret values for
* secret items stored in the service.
*
* Items that are locked will not have their secrets loaded.
*
* Returns: whether the operation succeded or not
*/
gboolean
secret_item_load_secrets_finish (GAsyncResult *result,
GError **error)
{
GSimpleAsyncResult *async;
g_return_val_if_fail (g_simple_async_result_is_valid (result, NULL,
secret_item_load_secrets), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
async = G_SIMPLE_ASYNC_RESULT (result);
if (g_simple_async_result_propagate_error (async, error))
return FALSE;
return TRUE;
}
/**
* secret_item_load_secrets_sync:
* @items: (element-type Secret.Item): the items to retrieve secrets for
* @cancellable: optional cancellation object
* @error: location to place an error on failure
*
* Load the secret values for an secret items stored in the service.
*
* The @items must all have the same SecretItem::service property.
*
* This method may block indefinitely and should not be used in user interface
* threads.
*
* Items that are locked will not have their secrets loaded.
*
* Returns: whether the operation succeded or not
*/
gboolean
secret_item_load_secrets_sync (GList *items,
GCancellable *cancellable,
GError **error)
{
SecretSync *sync;
gboolean ret;
GList *l;
for (l = items; l != NULL; l = g_list_next (l))
g_return_val_if_fail (SECRET_IS_ITEM (l->data), FALSE);
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
sync = _secret_sync_new ();
g_main_context_push_thread_default (sync->context);
secret_item_load_secrets (items, cancellable,
_secret_sync_on_result, sync);
g_main_loop_run (sync->loop);
ret = secret_item_load_secrets_finish (sync->result, error);
g_main_context_pop_thread_default (sync->context);
_secret_sync_free (sync);
return ret;
}
typedef struct {
GCancellable *cancellable;
SecretValue *value;

View File

@ -128,6 +128,18 @@ gboolean secret_item_load_secret_sync (SecretItem *self,
GCancellable *cancellable,
GError **error);
void secret_item_load_secrets (GList *items,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean secret_item_load_secrets_finish (GAsyncResult *result,
GError **error);
gboolean secret_item_load_secrets_sync (GList *items,
GCancellable *cancellable,
GError **error);
void secret_item_set_secret (SecretItem *self,
SecretValue *value,
GCancellable *cancellable,

View File

@ -321,69 +321,6 @@ secret_service_search_sync (SecretService *self,
return ret;
}
typedef struct {
GCancellable *cancellable;
GVariant *in;
GVariant *out;
GHashTable *items;
} GetClosure;
static void
get_closure_free (gpointer data)
{
GetClosure *closure = data;
if (closure->in)
g_variant_unref (closure->in);
if (closure->out)
g_variant_unref (closure->out);
g_clear_object (&closure->cancellable);
g_slice_free (GetClosure, closure);
}
static void
on_get_secrets_complete (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
GetClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
GError *error = NULL;
closure->out = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), result, &error);
if (error != NULL)
g_simple_async_result_take_error (res, error);
g_simple_async_result_complete (res);
g_object_unref (res);
}
static void
on_get_secrets_session (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
GetClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
GError *error = NULL;
const gchar *session;
session = secret_service_ensure_session_finish (SECRET_SERVICE (source),
result, &error);
if (error != NULL) {
g_simple_async_result_take_error (res, error);
g_simple_async_result_complete (res);
} else {
g_dbus_proxy_call (G_DBUS_PROXY (source), "GetSecrets",
g_variant_new ("(@aoo)", closure->in, session),
G_DBUS_CALL_FLAGS_NO_AUTO_START, -1,
closure->cancellable, on_get_secrets_complete,
g_object_ref (res));
}
g_object_unref (res);
}
SecretValue *
_secret_service_decode_get_secrets_first (SecretService *self,
GVariant *out)
@ -429,171 +366,6 @@ _secret_service_decode_get_secrets_all (SecretService *self,
return values;
}
/**
* secret_service_get_secrets:
* @self: the secret service
* @items: (element-type Secret.Item): the items to retrieve secrets for
* @cancellable: optional cancellation object
* @callback: called when the operation completes
* @user_data: data to pass to the callback
*
* Get the secret values for an secret items stored in the service.
*
* This method takes a list of #SecretItem proxy objects. If you only have the
* D-Bus object paths of the items, use secret_service_get_secrets_for_paths()
* instead.
*
* This function returns immediately and completes asynchronously.
*/
void
secret_service_get_secrets (SecretService *self,
GList *items,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
GSimpleAsyncResult *res;
GetClosure *closure;
GPtrArray *paths;
const gchar *path;
GList *l;
g_return_if_fail (SECRET_IS_SERVICE (self));
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
secret_service_get_secrets);
closure = g_slice_new0 (GetClosure);
closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
closure->items = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, g_object_unref);
paths = g_ptr_array_new ();
for (l = items; l != NULL; l = g_list_next (l)) {
path = g_dbus_proxy_get_object_path (l->data);
g_hash_table_insert (closure->items, g_strdup (path), g_object_ref (l->data));
g_ptr_array_add (paths, (gpointer)path);
}
closure->in = g_variant_new_objv ((const gchar * const *)paths->pdata, paths->len);
g_variant_ref_sink (closure->in);
g_ptr_array_free (paths, TRUE);
g_simple_async_result_set_op_res_gpointer (res, closure, get_closure_free);
secret_service_ensure_session (self, cancellable,
on_get_secrets_session,
g_object_ref (res));
g_object_unref (res);
}
/**
* secret_service_get_secrets_finish:
* @self: the secret service
* @result: asynchronous result passed to callback
* @error: location to place an error on failure
*
* Complete asynchronous operation to get the secret values for an
* secret items stored in the service.
*
* Items that are locked will not be included the results.
*
* Returns: (transfer full): a newly allocated hash table of #SecretItem keys
* to #SecretValue values.
*/
GHashTable *
secret_service_get_secrets_finish (SecretService *self,
GAsyncResult *result,
GError **error)
{
GSimpleAsyncResult *res;
GetClosure *closure;
GHashTable *with_paths;
GHashTable *with_items;
GHashTableIter iter;
const gchar *path;
SecretValue *value;
SecretItem *item;
g_return_val_if_fail (SECRET_IS_SERVICE (self), NULL);
g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self),
secret_service_get_secrets), NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
res = G_SIMPLE_ASYNC_RESULT (result);
if (g_simple_async_result_propagate_error (res, error))
return NULL;
closure = g_simple_async_result_get_op_res_gpointer (res);
with_paths = _secret_service_decode_get_secrets_all (self, closure->out);
g_return_val_if_fail (with_paths != NULL, NULL);
with_items = g_hash_table_new_full (g_direct_hash, g_direct_equal,
g_object_unref, secret_value_unref);
g_hash_table_iter_init (&iter, with_paths);
while (g_hash_table_iter_next (&iter, (gpointer *)&path, (gpointer *)&value)) {
item = g_hash_table_lookup (closure->items, path);
if (item != NULL)
g_hash_table_insert (with_items, g_object_ref (item),
secret_value_ref (value));
}
g_hash_table_unref (with_paths);
return with_items;
}
/**
* secret_service_get_secrets_sync:
* @self: the secret service
* @items: (element-type Secret.Item): the items to retrieve secrets for
* @cancellable: optional cancellation object
* @error: location to place an error on failure
*
* Get the secret values for an secret items stored in the service.
*
* This method takes a list of #SecretItem proxy objects. If you only have the
* D-Bus object paths of the items, use secret_service_get_secrets_for_paths_sync()
* instead.
*
* This method may block indefinitely and should not be used in user interface
* threads.
*
* Items that are locked will not be included the results.
*
* Returns: (transfer full): a newly allocated hash table of #SecretItem keys
* to #SecretValue values.
*/
GHashTable *
secret_service_get_secrets_sync (SecretService *self,
GList *items,
GCancellable *cancellable,
GError **error)
{
SecretSync *sync;
GHashTable *secrets;
g_return_val_if_fail (SECRET_IS_SERVICE (self), NULL);
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
sync = _secret_sync_new ();
g_main_context_push_thread_default (sync->context);
secret_service_get_secrets (self, items, cancellable,
_secret_sync_on_result, sync);
g_main_loop_run (sync->loop);
secrets = secret_service_get_secrets_finish (self, sync->result, error);
g_main_context_pop_thread_default (sync->context);
_secret_sync_free (sync);
return secrets;
}
typedef struct {
GCancellable *cancellable;
SecretPrompt *prompt;

View File

@ -445,7 +445,7 @@ secret_service_get_secret_for_path_sync (SecretService *self,
* Get the secret values for an secret items stored in the service.
*
* The items are represented by their D-Bus object paths. If you already have
* #SecretItem proxy objects, use use secret_service_get_secrets() to more simply
* #SecretItem proxy objects, use use secret_item_load_secrets() to more simply
* get their secret values.
*
* This function returns immediately and completes asynchronously.
@ -524,7 +524,7 @@ secret_service_get_secrets_for_paths_finish (SecretService *self,
* Get the secret values for an secret items stored in the service.
*
* The items are represented by their D-Bus object paths. If you already have
* #SecretItem proxy objects, use use secret_service_get_secrets_sync() to more
* #SecretItem proxy objects, use use secret_item_load_secrets_sync() to more
* simply get their secret values.
*
* This method may block indefinitely and should not be used in user interface

View File

@ -162,21 +162,6 @@ gboolean secret_service_search_sync (SecretService
GList **locked,
GError **error);
void secret_service_get_secrets (SecretService *self,
GList *items,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GHashTable * secret_service_get_secrets_finish (SecretService *self,
GAsyncResult *result,
GError **error);
GHashTable * secret_service_get_secrets_sync (SecretService *self,
GList *items,
GCancellable *cancellable,
GError **error);
void secret_service_lock (SecretService *self,
GList *objects,
GCancellable *cancellable,

View File

@ -624,6 +624,119 @@ test_set_secret_sync (Test *test,
g_object_unref (item);
}
static void
test_secrets_sync (Test *test,
gconstpointer used)
{
const gchar *path_item_one = "/org/freedesktop/secrets/collection/english/1";
const gchar *path_item_two = "/org/freedesktop/secrets/collection/english/2";
const gchar *path_item_three = "/org/freedesktop/secrets/collection/spanish/10";
SecretValue *value;
GError *error = NULL;
const gchar *password;
SecretItem *item_one, *item_two, *item_three;
GList *items = NULL;
gboolean ret;
gsize length;
item_one = secret_item_new_sync (test->service, path_item_one, SECRET_ITEM_NONE, NULL, &error);
item_two = secret_item_new_sync (test->service, path_item_two, SECRET_ITEM_NONE, NULL, &error);
item_three = secret_item_new_sync (test->service, path_item_three, SECRET_ITEM_NONE, NULL, &error);
items = g_list_append (items, item_one);
items = g_list_append (items, item_two);
items = g_list_append (items, item_three);
ret = secret_item_load_secrets_sync (items, NULL, &error);
g_assert_no_error (error);
g_assert (ret == TRUE);
value = secret_item_get_secret (item_one);
g_assert (value != NULL);
password = secret_value_get (value, &length);
g_assert_cmpuint (length, ==, 3);
g_assert_cmpstr (password, ==, "111");
secret_value_unref (value);
value = secret_item_get_secret (item_two);
g_assert (value != NULL);
password = secret_value_get (value, &length);
g_assert_cmpuint (length, ==, 3);
g_assert_cmpstr (password, ==, "222");
secret_value_unref (value);
value = secret_item_get_secret (item_three);
g_assert (value == NULL);
g_list_free_full (items, g_object_unref);
}
static void
test_secrets_async (Test *test,
gconstpointer used)
{
const gchar *path_item_one = "/org/freedesktop/secrets/collection/english/1";
const gchar *path_item_two = "/org/freedesktop/secrets/collection/english/2";
const gchar *path_item_three = "/org/freedesktop/secrets/collection/spanish/10";
SecretValue *value;
GError *error = NULL;
const gchar *password;
GAsyncResult *result = NULL;
SecretItem *item_one, *item_two, *item_three;
GList *items = NULL;
gsize length;
gboolean ret;
item_one = secret_item_new_sync (test->service, path_item_one, SECRET_ITEM_NONE, NULL, &error);
g_assert_no_error (error);
item_two = secret_item_new_sync (test->service, path_item_two, SECRET_ITEM_NONE, NULL, &error);
g_assert_no_error (error);
item_three = secret_item_new_sync (test->service, path_item_three, SECRET_ITEM_NONE, NULL, &error);
g_assert_no_error (error);
items = g_list_append (items, item_one);
items = g_list_append (items, item_two);
items = g_list_append (items, item_three);
secret_item_load_secrets (items, NULL,
on_async_result, &result);
g_assert (result == NULL);
egg_test_wait ();
ret = secret_item_load_secrets_finish (result, &error);
g_assert_no_error (error);
g_object_unref (result);
g_assert (ret == TRUE);
value = secret_item_get_secret (item_one);
g_assert (value != NULL);
password = secret_value_get (value, &length);
g_assert_cmpuint (length, ==, 3);
g_assert_cmpstr (password, ==, "111");
secret_value_unref (value);
value = secret_item_get_secret (item_two);
g_assert (value != NULL);
password = secret_value_get (value, &length);
g_assert_cmpuint (length, ==, 3);
g_assert_cmpstr (password, ==, "222");
secret_value_unref (value);
value = secret_item_get_secret (item_three);
g_assert (value == NULL);
g_object_unref (item_one);
g_object_unref (item_two);
g_object_unref (item_three);
g_list_free (items);
}
static void
test_delete_sync (Test *test,
gconstpointer unused)
@ -699,6 +812,8 @@ main (int argc, char **argv)
g_test_add ("/item/load-secret-sync", Test, "mock-service-normal.py", setup, test_load_secret_sync, teardown);
g_test_add ("/item/load-secret-async", Test, "mock-service-normal.py", setup, test_load_secret_async, teardown);
g_test_add ("/item/set-secret-sync", Test, "mock-service-normal.py", setup, test_set_secret_sync, teardown);
g_test_add ("/item/secrets-sync", Test, "mock-service-normal.py", setup, test_secrets_sync, teardown);
g_test_add ("/item/secrets-async", Test, "mock-service-normal.py", setup, test_secrets_async, teardown);
g_test_add ("/item/delete-sync", Test, "mock-service-normal.py", setup, test_delete_sync, teardown);
g_test_add ("/item/delete-async", Test, "mock-service-normal.py", setup, test_delete_async, teardown);

View File

@ -257,116 +257,6 @@ test_search_nulls (Test *test,
g_hash_table_unref (attributes);
}
static void
test_secrets_sync (Test *test,
gconstpointer used)
{
const gchar *path_item_one = "/org/freedesktop/secrets/collection/english/1";
const gchar *path_item_two = "/org/freedesktop/secrets/collection/english/2";
const gchar *path_item_three = "/org/freedesktop/secrets/collection/spanish/10";
SecretValue *value;
GHashTable *values;
GError *error = NULL;
const gchar *password;
SecretItem *item_one, *item_two, *item_three;
GList *items = NULL;
gsize length;
item_one = secret_item_new_sync (test->service, path_item_one, SECRET_ITEM_NONE, NULL, &error);
item_two = secret_item_new_sync (test->service, path_item_two, SECRET_ITEM_NONE, NULL, &error);
item_three = secret_item_new_sync (test->service, path_item_three, SECRET_ITEM_NONE, NULL, &error);
items = g_list_append (items, item_one);
items = g_list_append (items, item_two);
items = g_list_append (items, item_three);
values = secret_service_get_secrets_sync (test->service, items, NULL, &error);
g_list_free_full (items, g_object_unref);
g_assert_no_error (error);
g_assert (values != NULL);
g_assert_cmpuint (g_hash_table_size (values), ==, 2);
value = g_hash_table_lookup (values, item_one);
g_assert (value != NULL);
password = secret_value_get (value, &length);
g_assert_cmpuint (length, ==, 3);
g_assert_cmpstr (password, ==, "111");
value = g_hash_table_lookup (values, item_two);
g_assert (value != NULL);
password = secret_value_get (value, &length);
g_assert_cmpuint (length, ==, 3);
g_assert_cmpstr (password, ==, "222");
g_hash_table_unref (values);
}
static void
test_secrets_async (Test *test,
gconstpointer used)
{
const gchar *path_item_one = "/org/freedesktop/secrets/collection/english/1";
const gchar *path_item_two = "/org/freedesktop/secrets/collection/english/2";
const gchar *path_item_three = "/org/freedesktop/secrets/collection/spanish/10";
SecretValue *value;
GHashTable *values;
GError *error = NULL;
const gchar *password;
GAsyncResult *result = NULL;
SecretItem *item_one, *item_two, *item_three;
GList *items = NULL;
gsize length;
item_one = secret_item_new_sync (test->service, path_item_one, SECRET_ITEM_NONE, NULL, &error);
g_assert_no_error (error);
item_two = secret_item_new_sync (test->service, path_item_two, SECRET_ITEM_NONE, NULL, &error);
g_assert_no_error (error);
item_three = secret_item_new_sync (test->service, path_item_three, SECRET_ITEM_NONE, NULL, &error);
g_assert_no_error (error);
items = g_list_append (items, item_one);
items = g_list_append (items, item_two);
items = g_list_append (items, item_three);
secret_service_get_secrets (test->service, items, NULL,
on_complete_get_result, &result);
g_assert (result == NULL);
g_list_free (items);
egg_test_wait ();
values = secret_service_get_secrets_finish (test->service, result, &error);
g_assert_no_error (error);
g_object_unref (result);
g_assert (values != NULL);
g_assert_cmpuint (g_hash_table_size (values), ==, 2);
value = g_hash_table_lookup (values, item_one);
g_assert (value != NULL);
password = secret_value_get (value, &length);
g_assert_cmpuint (length, ==, 3);
g_assert_cmpstr (password, ==, "111");
value = g_hash_table_lookup (values, item_two);
g_assert (value != NULL);
password = secret_value_get (value, &length);
g_assert_cmpuint (length, ==, 3);
g_assert_cmpstr (password, ==, "222");
g_hash_table_unref (values);
g_object_unref (item_one);
g_object_unref (item_two);
g_object_unref (item_three);
}
static void
test_lock_sync (Test *test,
gconstpointer used)
@ -938,9 +828,6 @@ main (int argc, char **argv)
g_test_add ("/service/search-async", Test, "mock-service-normal.py", setup, test_search_async, teardown);
g_test_add ("/service/search-nulls", Test, "mock-service-normal.py", setup, test_search_nulls, teardown);
g_test_add ("/service/secrets-sync", Test, "mock-service-normal.py", setup, test_secrets_sync, teardown);
g_test_add ("/service/secrets-async", Test, "mock-service-normal.py", setup, test_secrets_async, teardown);
g_test_add ("/service/lock-sync", Test, "mock-service-lock.py", setup, test_lock_sync, teardown);
g_test_add ("/service/unlock-sync", Test, "mock-service-lock.py", setup, test_unlock_sync, teardown);