Simple test for gsecret_service_search_paths()

This commit is contained in:
Stef Walter 2011-11-05 21:50:01 +01:00 committed by Stef Walter
parent 737e3a1ca3
commit 7ac228b62f
10 changed files with 204 additions and 24 deletions

3
.gitignore vendored
View File

@ -37,4 +37,5 @@ stamp*
/egg/tests/test-hkdf
/egg/tests/test-secmem
/library/tests/test-session
/library/tests/test-*
!/library/tests/test-*.c

View File

@ -30,6 +30,8 @@ G_BEGIN_DECLS
gchar * _gsecret_util_parent_path (const gchar *path);
GVariant * _gsecret_util_variant_for_attributes (GHashTable *attributes);
GSecretService * _gsecret_service_bare_instance (GDBusConnection *connection,
const gchar *bus_name);

View File

@ -869,24 +869,6 @@ _gsecret_service_encode_secret (GSecretService *self,
return result;
}
static GVariant *
_gsecret_util_variant_for_attributes (GHashTable *attributes)
{
GHashTableIter iter;
GVariantBuilder builder;
const gchar *name;
const gchar *value;
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ssv)"));
g_hash_table_iter_init (&iter, attributes);
while (g_hash_table_iter_next (&iter, (gpointer *)&name, (gpointer *)&value))
g_variant_builder_add (&builder, "(ss)", name, value);
return g_variant_builder_end (&builder);
}
static void
on_search_items_complete (GObject *source,
GAsyncResult *result,
@ -924,7 +906,8 @@ gsecret_service_search_paths (GSecretService *self,
gsecret_service_search_paths);
g_dbus_proxy_call (G_DBUS_PROXY (self), "SearchItems",
_gsecret_util_variant_for_attributes (attributes),
g_variant_new ("(@a{ss})",
_gsecret_util_variant_for_attributes (attributes)),
G_DBUS_CALL_FLAGS_NONE, -1, cancellable,
on_search_items_complete, g_object_ref (res));
@ -980,7 +963,8 @@ gsecret_service_search_paths_sync (GSecretService *self,
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
response = g_dbus_proxy_call_sync (G_DBUS_PROXY (self), "SearchItems",
_gsecret_util_variant_for_attributes (attributes),
g_variant_new ("(@a{ss})",
_gsecret_util_variant_for_attributes (attributes)),
G_DBUS_CALL_FLAGS_NONE, -1, cancellable, error);
if (response != NULL) {

View File

@ -45,3 +45,23 @@ _gsecret_util_parent_path (const gchar *path)
pos--;
return g_strndup (path, pos - path);
}
GVariant *
_gsecret_util_variant_for_attributes (GHashTable *attributes)
{
GHashTableIter iter;
GVariantBuilder builder;
const gchar *name;
const gchar *value;
g_return_val_if_fail (attributes != NULL, NULL);
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}"));
g_hash_table_iter_init (&iter, attributes);
while (g_hash_table_iter_next (&iter, (gpointer *)&name, (gpointer *)&value))
g_variant_builder_add (&builder, "{ss}", name, value);
return g_variant_builder_end (&builder);
}

View File

@ -11,6 +11,7 @@ LDADD = \
$(NULL)
TEST_PROGS = \
test-service \
test-session \
$(NULL)

View File

@ -3,4 +3,15 @@
import mock
service = mock.SecretService()
collection = mock.SecretCollection(service, "collection", locked=False)
mock.SecretItem(collection, "item_one", attributes={ "number": "1", "string": "one", "parity": "odd" })
mock.SecretItem(collection, "item_two", attributes={ "number": "2", "string": "two", "parity": "even" })
mock.SecretItem(collection, "item_three", attributes={ "number": "3", "string": "three", "parity": "odd" })
collection = mock.SecretCollection(service, "second", locked=True)
mock.SecretItem(collection, "item_one", attributes={ "number": "1", "string": "one", "parity": "odd" })
mock.SecretItem(collection, "item_two", attributes={ "number": "2", "string": "two", "parity": "even" })
mock.SecretItem(collection, "item_three", attributes={ "number": "3", "string": "three", "parity": "odd" })
service.listen()

View File

@ -73,6 +73,43 @@ class SecretSession(dbus.service.Object):
self.remove_from_connection()
self.service.remove_session(self)
class SecretItem(dbus.service.Object):
def __init__(self, collection, identifier, label="Item", attributes={ }):
self.collection = collection
self.identifier = identifier
self.label = label
self.attributes = attributes
self.path = "/org/freedesktop/secrets/collection/%s/%s" % (collection.identifier, identifier)
dbus.service.Object.__init__(self, collection.service.bus_name, self.path)
collection.items[identifier] = self
def match_attributes(self, attributes):
for (key, value) in attributes.items():
if not self.attributes.get(key) == value:
return False
return True
class SecretCollection(dbus.service.Object):
def __init__(self, service, identifier, label="Collection", locked=False):
self.service = service
self.identifier = identifier
self.label = label
self.locked = locked
self.items = { }
self.path = "/org/freedesktop/secrets/collection/%s" % identifier
dbus.service.Object.__init__(self, service.bus_name, self.path)
service.collections[identifier] = self
def search_items(self, attributes):
results = []
for item in self.items.values():
if item.match_attributes(attributes):
results.append(item)
return results
class SecretService(dbus.service.Object):
algorithms = {
@ -87,6 +124,7 @@ class SecretService(dbus.service.Object):
self.bus_name = dbus.service.BusName(name, allow_replacement=True, replace_existing=True)
dbus.service.Object.__init__(self, self.bus_name, '/org/freedesktop/secrets')
self.sessions = { }
self.collections = { }
def on_name_owner_changed(owned, old_owner, new_owner):
if not new_owner:
@ -118,6 +156,20 @@ class SecretService(dbus.service.Object):
return self.algorithms[algorithm].negotiate(self, sender, param)
@dbus.service.method('org.freedesktop.Secret.Service')
def SearchItems(self, attributes):
locked = [ ]
unlocked = [ ]
items = [ ]
for collection in self.collections.values():
items = collection.search_items(attributes)
if collection.locked:
locked.extend(items)
else:
unlocked.extend(items)
return (dbus.Array(unlocked, "o"), dbus.Array(locked, "o"))
def parse_options(args):
global bus_name
try:

View File

@ -0,0 +1,109 @@
/* GSecret - GLib wrapper for Secret Service
*
* Copyright 2011 Collabora Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2 of the licence or (at
* your option) any later version.
*
* See the included COPYING file for more information.
*/
#include "config.h"
#include "gsecret-service.h"
#include "gsecret-private.h"
#include "egg/egg-testing.h"
#include <glib.h>
#include <errno.h>
#include <stdlib.h>
static gchar *MOCK_NAME = "org.mock.Service";
typedef struct {
GPid pid;
GDBusConnection *connection;
GSecretService *service;
} Test;
static void
setup (Test *test,
gconstpointer data)
{
GError *error = NULL;
const gchar *mock_script = data;
gchar *argv[] = {
"python", (gchar *)mock_script,
"--name", MOCK_NAME,
NULL
};
g_spawn_async (SRCDIR, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, &test->pid, &error);
g_assert_no_error (error);
g_usleep (200 * 1000);
test->connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
g_assert_no_error (error);
test->service = _gsecret_service_bare_instance (test->connection, MOCK_NAME);
}
static void
teardown (Test *test,
gconstpointer unused)
{
g_clear_object (&test->service);
g_clear_object (&test->connection);
g_assert (test->pid);
if (kill (test->pid, SIGTERM) < 0)
g_error ("kill() failed: %s", g_strerror (errno));
g_spawn_close_pid (test->pid);
}
static void
test_search_paths (Test *test,
gconstpointer used)
{
GHashTable *attributes;
gboolean ret;
gchar **locked;
gchar **unlocked;
GError *error = NULL;
attributes = g_hash_table_new (g_str_hash, g_str_equal);
g_hash_table_insert (attributes, "number", "1");
ret = gsecret_service_search_paths_sync (test->service, attributes, NULL,
&unlocked, &locked, &error);
g_assert_no_error (error);
g_assert (ret == TRUE);
g_assert (locked);
g_assert_cmpstr (locked[0], ==, "/org/freedesktop/secrets/collection/second/item_one");
g_assert (unlocked);
g_assert_cmpstr (unlocked[0], ==, "/org/freedesktop/secrets/collection/collection/item_one");
g_strfreev (unlocked);
g_strfreev (locked);
g_hash_table_unref (attributes);
}
int
main (int argc, char **argv)
{
g_test_init (&argc, &argv, NULL);
g_set_prgname ("test-service");
g_type_init ();
g_test_add ("/service/search-paths", Test, "mock-service-normal.py", setup, test_search_paths, teardown);
return egg_tests_run_in_thread_with_loop ();
}

View File

@ -46,7 +46,7 @@ setup (Test *test,
g_spawn_async (SRCDIR, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, &test->pid, &error);
g_assert_no_error (error);
g_usleep (100 * 1000);
g_usleep (200 * 1000);
test->connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
g_assert_no_error (error);

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-11-05 20:58+0100\n"
"POT-Creation-Date: 2011-11-05 21:48+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"