/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/*
Copyright (C) 2010 Collabora Ltd
The Gnome Keyring Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The Gnome Keyring Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the Gnome Library; see the file COPYING.LIB. If not,
see <http://www.gnu.org/licenses/>.
Author: Stef Walter <stefw@collabora.co.uk>
*/
#include "config.h"
#include "gcr/gcr-base.h"
#include "gcr/gcr-gnupg-collection.h"
#include "gcr/gcr-gnupg-key.h"
#include "gcr/gcr-record.h"
#include "egg/egg-testing.h"
#include <glib.h>
#include <glib/gstdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
GcrGnupgCollection *collection;
gchar *directory;
GHashTable *keys;
GAsyncResult *result;
} Test;
static void
on_collection_added (GcrCollection *collection, GObject *object, gpointer user_data)
{
Test *test = user_data;
GcrGnupgKey *key;
const gchar *keyid;
g_assert (GCR_COLLECTION (test->collection) == collection);
g_assert (GCR_IS_GNUPG_KEY (object));
key = GCR_GNUPG_KEY (object);
keyid = _gcr_gnupg_key_get_keyid (key);
g_assert (keyid);
g_assert (!g_hash_table_lookup (test->keys, keyid));
g_hash_table_insert (test->keys, g_strdup (keyid), key);
}
static void
on_collection_removed (GcrCollection *collection, GObject *object, gpointer user_data)
{
Test *test = user_data;
GcrGnupgKey *key;
const gchar *keyid;
g_assert (GCR_COLLECTION (test->collection) == collection);
g_assert (GCR_IS_GNUPG_KEY (object));
keyid = _gcr_gnupg_key_get_keyid (GCR_GNUPG_KEY (object));
key = g_hash_table_lookup (test->keys, keyid);
g_assert (key == GCR_GNUPG_KEY (object));
if (!g_hash_table_remove (test->keys, keyid))
g_assert_not_reached ();
}
static void
setup (Test *test, gconstpointer unused)
{
GcrCollection *collection;
GError *error = NULL;
gchar *cmd;
test->directory = g_build_filename ("/tmp/gcr-tests.XXXXXX", NULL);
g_assert (g_mkdtemp_full (test->directory, 0700) != NULL);
cmd = g_strdup_printf ("cp -p " SRCDIR "/gcr/fixtures/gnupg-homedir/* %s", test->directory);
g_spawn_check_exit_status (system (cmd), &error);
g_assert_no_error (error);
g_free (cmd);
collection = _gcr_gnupg_collection_new (test->directory);
test->collection = GCR_GNUPG_COLLECTION (collection);
test->keys = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
g_signal_connect (collection, "added", G_CALLBACK (on_collection_added), test);
g_signal_connect (collection, "removed", G_CALLBACK (on_collection_removed), test);
}
static void
teardown (Test *test, gconstpointer unused)
{
GError *error = NULL;
gchar *cmd;
g_hash_table_destroy (test->keys);
if (test->result)
g_object_unref (test->result);
g_object_unref (test->collection);
/* remove potential gpg 2.1 extras, ignore any errors. */
cmd = g_strdup_printf ("rm -rf %s/*.d", test->directory);
system (cmd);
g_free (cmd);
cmd = g_strdup_printf ("rm -f %s/.gpg-v21-migrated", test->directory);
system (cmd);
g_free (cmd);
cmd = g_strdup_printf ("rm -f %s/*", test->directory);
g_spawn_check_exit_status (system (cmd), &error);
g_assert_no_error (error);
g_free (cmd);
if (g_rmdir (test->directory) < 0)
g_critical ("couldn't remove %s: %s", test->directory, g_strerror (errno));
g_free (test->directory);
}
static void
on_async_ready (GObject *source, GAsyncResult *res, gpointer user_data)
{
Test *test = user_data;
g_assert (G_OBJECT (test->collection) == source);
g_assert (test->result == NULL);
test->result = g_object_ref (res);
egg_test_wait_stop ();
}
static void
test_properties (Test *test, gconstpointer unused)
{
gchar *directory;
g_object_get (test->collection, "directory", &directory, NULL);
g_assert_cmpstr (directory, ==, test->directory);
g_free (directory);
}
static void
test_load (Test *test, gconstpointer unused)
{
GError *error = NULL;
GcrGnupgKey *key;
GList *l, *objects;
GcrRecord *record;
GHashTable *check;
_gcr_gnupg_collection_load_async (test->collection, NULL, on_async_ready, test);
egg_test_wait_until (500000);
g_assert (test->result);
_gcr_gnupg_collection_load_finish (test->collection, test->result, &error);
g_assert_no_error (error);
/* Werner Koch (a public key) */
key = g_hash_table_lookup (test->keys, "5DE249965B0358A2");
g_assert (GCR_IS_GNUPG_KEY (key));
g_assert (_gcr_gnupg_key_get_secret_records (key) == NULL);
/* Test Number 2 (a secret key)*/
key = g_hash_table_lookup (test->keys, "268FEE686262C395");
g_assert (GCR_IS_GNUPG_KEY (key));
g_assert (_gcr_gnupg_key_get_secret_records (key));
/* The length of collection should be correct */
g_assert_cmpuint (g_hash_table_size (test->keys), ==,
gcr_collection_get_length (GCR_COLLECTION (test->collection)));
/* The list of objects should be correct */
objects = gcr_collection_get_objects (GCR_COLLECTION (test->collection));
g_assert_cmpuint (g_hash_table_size (test->keys), ==, g_list_length (objects));
check = g_hash_table_new (g_str_hash, g_str_equal);
for (l = objects; l != NULL; l = g_list_next (l)) {
g_assert (GCR_IS_GNUPG_KEY (l->data));
key = g_hash_table_lookup (test->keys, _gcr_gnupg_key_get_keyid (l->data));
g_assert (key == l->data);
g_hash_table_replace (check, (gchar*)_gcr_gnupg_key_get_keyid (l->data), "");
}
g_assert_cmpuint (g_hash_table_size (check), ==, g_hash_table_size (test->keys));
g_hash_table_destroy (check);
g_list_free (objects);
/* Phillip R. Zimmerman's key should have a photo */
key = g_hash_table_lookup (test->keys, "C7463639B2D7795E");
g_assert (GCR_IS_GNUPG_KEY (key));
record = _gcr_records_find (_gcr_gnupg_key_get_public_records (key), GCR_RECORD_SCHEMA_XA1);
g_assert (record);
}
static void
test_reload (Test *test, gconstpointer unused)
{
GError *error = NULL;
GcrGnupgKey *key;
_gcr_gnupg_collection_load_async (test->collection, NULL, on_async_ready, test);
egg_test_wait_until (2500);
g_assert (test->result);
_gcr_gnupg_collection_load_finish (test->collection, test->result, &error);
g_assert_no_error (error);
g_object_unref (test->result);
test->result = NULL;
_gcr_gnupg_collection_load_async (test->collection, NULL, on_async_ready, test);
egg_test_wait_until (500000);
g_assert (test->result);
_gcr_gnupg_collection_load_finish (test->collection, test->result, &error);
g_assert_no_error (error);
/* Werner Koch (a public key) */
key = g_hash_table_lookup (test->keys, "5DE249965B0358A2");
g_assert (GCR_IS_GNUPG_KEY (key));
g_assert (_gcr_gnupg_key_get_secret_records (key) == NULL);
/* Test Number 2 (a secret key)*/
key = g_hash_table_lookup (test->keys, "268FEE686262C395");
g_assert (GCR_IS_GNUPG_KEY (key));
g_assert (_gcr_gnupg_key_get_secret_records (key));
}
int
main (int argc, char **argv)
{
g_test_init (&argc, &argv, NULL);
g_set_prgname ("test-gnupg-collection");
g_test_add ("/gcr/gnupg-collection/properties", Test, NULL, setup, test_properties, teardown);
g_test_add ("/gcr/gnupg-collection/load", Test, NULL, setup, test_load, teardown);
g_test_add ("/gcr/gnupg-collection/reload", Test, NULL, setup, test_reload, teardown);
return egg_tests_run_with_loop ();
}