#include <config.h>
#include <glib.h>
#include <glib-object.h>
#include <glib/gstdio.h>
#include "pk-backend.h"
#include "pk-backend-spawn.h"
#include "pk-dbus.h"
#include "pk-engine.h"
#include "pk-spawn.h"
#include "pk-transaction-db.h"
#include "pk-transaction.h"
#include "pk-transaction-private.h"
#include "pk-scheduler.h"
#define PK_TRANSACTION_ERROR_INPUT_INVALID 14
static GMainLoop *_test_loop = NULL;
static guint _test_loop_timeout_id = 0;
static gboolean
_g_test_hang_check_cb (gpointer user_data)
{
guint timeout_ms = *((guint*) user_data);
g_main_loop_quit (_test_loop);
g_warning ("loop not completed in %ims", timeout_ms);
g_assert_not_reached ();
return FALSE;
}
static void
_g_test_loop_run_with_timeout (guint timeout_ms)
{
g_assert_true (_test_loop_timeout_id == 0);
_test_loop = g_main_loop_new (NULL, FALSE);
_test_loop_timeout_id = g_timeout_add (timeout_ms, _g_test_hang_check_cb, &timeout_ms);
g_main_loop_run (_test_loop);
}
static gboolean
_g_test_hang_wait_cb (gpointer user_data)
{
g_main_loop_quit (_test_loop);
_test_loop_timeout_id = 0;
return FALSE;
}
static void
_g_test_loop_wait (guint timeout_ms)
{
g_assert_true (_test_loop_timeout_id == 0);
_test_loop = g_main_loop_new (NULL, FALSE);
_test_loop_timeout_id = g_timeout_add (timeout_ms, _g_test_hang_wait_cb, &timeout_ms);
g_main_loop_run (_test_loop);
}
static void
_g_test_loop_quit (void)
{
if (_test_loop_timeout_id > 0) {
g_source_remove (_test_loop_timeout_id);
_test_loop_timeout_id = 0;
}
if (_test_loop != NULL) {
g_main_loop_quit (_test_loop);
g_main_loop_unref (_test_loop);
_test_loop = NULL;
}
}
static guint number_packages = 0;
static void
pk_test_backend_finished_cb (PkBackend *backend, PkExitEnum exit, gpointer user_data)
{
_g_test_loop_quit ();
}
static void
pk_test_backend_watch_file_cb (PkBackend *backend, gpointer user_data)
{
_g_test_loop_quit ();
}
static void
pk_test_backend_func_true (PkBackendJob *job,
GVariant *params,
gpointer user_data)
{
g_usleep (1000*1000);
g_assert_cmpint (GPOINTER_TO_INT (user_data), ==, 999);
pk_backend_job_package (job, PK_INFO_ENUM_AVAILABLE,
"vips-doc;7.12.4-2.fc8;noarch;linva",
"The vips documentation package.");
pk_backend_job_package (job, PK_INFO_ENUM_AVAILABLE,
"vips-doc;7.12.4-2.fc8;noarch;linva",
"The vips documentation package.");
}
static void
pk_test_backend_func_immediate_false (PkBackendJob *job,
GVariant *params,
gpointer user_data)
{
}
static void
pk_test_backend_package_cb (PkBackend *backend, PkPackage *package, gpointer user_data)
{
g_debug ("package:%s", pk_package_get_id (package));
number_packages++;
}
static void
pk_test_backend_packages_cb (PkBackend *backend, GPtrArray *package_array, gpointer user_data)
{
for (guint i = 0; i < package_array->len; i++) {
PkPackage *package = g_ptr_array_index (package_array, i);
g_debug ("package:%s", pk_package_get_id (package));
number_packages++;
}
}
static void
pk_test_backend_func (void)
{
const gchar *text;
gboolean ret;
const gchar *filename;
GError *error = NULL;
g_autoptr(GKeyFile) conf = NULL;
g_autoptr(PkBackend) backend = NULL;
g_autoptr(PkBackendJob) job = NULL;
conf = g_key_file_new ();
backend = pk_backend_new (conf);
g_assert_true (backend != NULL);
filename = "/tmp/dave";
ret = g_file_set_contents (filename, "foo", -1, NULL);
g_assert_true (ret);
ret = pk_backend_watch_file (backend, filename, (PkBackendFileChanged) pk_test_backend_watch_file_cb, NULL);
g_assert_true (ret);
ret = g_file_set_contents (filename, "bar", -1, NULL);
g_assert_true (ret);
_g_test_loop_run_with_timeout (5000);
ret = g_unlink (filename);
g_assert_true (!ret);
_g_test_loop_run_with_timeout (5000);
job = pk_backend_job_new (conf);
pk_backend_job_set_backend (job, backend);
pk_backend_job_set_vfunc (job,
PK_BACKEND_SIGNAL_PACKAGE,
PK_BACKEND_JOB_VFUNC (pk_test_backend_package_cb),
NULL);
pk_backend_job_set_vfunc (job,
PK_BACKEND_SIGNAL_PACKAGES,
PK_BACKEND_JOB_VFUNC (pk_test_backend_packages_cb),
NULL);
pk_backend_job_set_vfunc (job,
PK_BACKEND_SIGNAL_FINISHED,
PK_BACKEND_JOB_VFUNC (pk_test_backend_finished_cb),
NULL);
ret = pk_backend_is_eula_valid (backend, "license_foo");
g_assert_true (!ret);
pk_backend_accept_eula (backend, "license_foo");
ret = pk_backend_is_eula_valid (backend, "license_foo");
g_assert_true (ret);
pk_backend_accept_eula (backend, "license_foo");
g_key_file_set_string (conf, "Daemon", "DefaultBackend", "invalid");
ret = pk_backend_load (backend, &error);
g_assert_error (error, 1, 0);
g_assert_true (!ret);
g_clear_error (&error);
g_key_file_set_string (conf, "Daemon", "DefaultBackend", "dummy");
ret = pk_backend_load (backend, &error);
g_assert_no_error (error);
g_assert_true (ret);
ret = pk_backend_load (backend, &error);
g_assert_error (error, 1, 0);
g_assert_true (!ret);
g_clear_error (&error);
text = pk_backend_get_name (backend);
g_assert_cmpstr (text, ==, "dummy");
ret = pk_backend_unload (backend);
g_assert_true (ret);
ret = pk_backend_unload (backend);
g_assert_true (ret);
ret = pk_backend_job_get_is_finished (job);
g_assert_true (!ret);
ret = pk_backend_job_has_set_error_code (job);
g_assert_true (!ret);
ret = pk_backend_load (backend, &error);
g_assert_no_error (error);
g_assert_true (ret);
ret = pk_backend_job_thread_create (job,
pk_test_backend_func_true,
GINT_TO_POINTER (999),
NULL);
g_assert_true (ret);
_g_test_loop_wait (2000);
g_assert_cmpint (number_packages, ==, 1);
g_object_unref (job);
job = pk_backend_job_new (conf);
pk_backend_job_set_backend (job, backend);
ret = pk_backend_job_thread_create (job,
pk_test_backend_func_immediate_false,
NULL,
NULL);
g_assert_true (ret);
_g_test_loop_wait (10);
g_object_unref (job);
job = pk_backend_job_new (conf);
pk_backend_job_set_backend (job, backend);
pk_backend_job_error_code (job, PK_ERROR_ENUM_GPG_FAILURE, "test error");
g_assert_cmpint (pk_backend_job_get_exit_code (job), ==,
PK_EXIT_ENUM_NEED_UNTRUSTED);
}
static guint _backend_spawn_number_packages = 0;
static void
pk_test_backend_spawn_finished_cb (PkBackendJob *job,
PkExitEnum exit,
PkBackendSpawn *backend_spawn)
{
_g_test_loop_quit ();
}
static void
pk_test_backend_spawn_package_cb (PkBackend *backend, PkInfoEnum info,
const gchar *package_id, const gchar *summary,
PkBackendSpawn *backend_spawn)
{
_backend_spawn_number_packages++;
}
static void
pk_test_backend_spawn_packages_cb (PkBackend *backend, GPtrArray *package_array,
PkBackendSpawn *backend_spawn)
{
_backend_spawn_number_packages += package_array->len;
}
static void
pk_test_backend_spawn_func (void)
{
PkBackendSpawn *backend_spawn;
const gchar *text;
gboolean ret;
gchar *uri;
g_autoptr(GKeyFile) conf = NULL;
g_autoptr(PkBackend) backend = NULL;
g_autoptr(PkBackendJob) job = NULL;
g_autoptr(GError) error = NULL;
conf = g_key_file_new ();
g_key_file_set_string (conf, "Daemon", "DefaultBackend", "test_spawn");
backend_spawn = pk_backend_spawn_new (conf);
g_assert_true (backend_spawn != NULL);
backend = pk_backend_new (conf);
job = pk_backend_job_new (conf);
pk_backend_job_set_backend (job, backend);
text = pk_backend_spawn_get_name (backend_spawn);
g_assert_cmpstr (text, ==, NULL);
ret = pk_backend_spawn_set_name (backend_spawn, "test_spawn");
g_assert_true (ret);
text = pk_backend_spawn_get_name (backend_spawn);
g_assert_cmpstr (text, ==, "test_spawn");
ret = pk_backend_spawn_inject_data (backend_spawn, job, "percentage\t0", &error);
g_assert_no_error (error);
g_assert_true (ret);
ret = pk_backend_spawn_inject_data (backend_spawn, job, "percentage\tbrian", NULL);
g_assert_true (!ret);
ret = pk_backend_spawn_inject_data (backend_spawn, job, "percentage\t12345", NULL);
g_assert_true (!ret);
ret = pk_backend_spawn_inject_data (backend_spawn, job, "percentage\t", NULL);
g_assert_true (!ret);
ret = pk_backend_spawn_inject_data (backend_spawn, job, "percentage", NULL);
g_assert_true (!ret);
ret = pk_backend_spawn_inject_data (backend_spawn, job, "no-percentage-updates", NULL);
g_assert_true (ret);
ret = pk_backend_spawn_inject_data (backend_spawn, job, "error\tnot-present-woohoo\tdescription text", NULL);
g_assert_true (!ret);
ret = pk_backend_spawn_inject_data (backend_spawn, job, "status\tquery", NULL);
g_assert_true (ret);
ret = pk_backend_spawn_inject_data (backend_spawn, job, "requirerestart\tsystem\tgnome-power-manager;0.0.1;i386;data", NULL);
g_assert_true (ret);
ret = pk_backend_spawn_inject_data (backend_spawn, job, "requirerestart\tmooville\tgnome-power-manager;0.0.1;i386;data", NULL);
g_assert_true (!ret);
ret = pk_backend_spawn_inject_data (backend_spawn, job, "requirerestart\tsystem\tdetails about the restart", NULL);
g_assert_true (!ret);
ret = pk_backend_spawn_inject_data (backend_spawn, job, "allow-cancel\ttrue", NULL);
g_assert_true (ret);
ret = pk_backend_spawn_inject_data (backend_spawn, job, "allow-cancel\tbrian", NULL);
g_assert_true (!ret);
uri = pk_backend_convert_uri ("username:password@server:port");
g_assert_cmpstr (uri, ==, "http://username:password@server:port/");
g_free (uri);
uri = pk_backend_convert_uri ("http://username:password@server:port/");
g_assert_cmpstr (uri, ==, "http://username:password@server:port/");
g_free (uri);
uri = pk_backend_convert_uri ("ftp://username:password@server:port");
g_assert_cmpstr (uri, ==, "ftp://username:password@server:port/");
g_free (uri);
ret = pk_backend_spawn_inject_data (backend_spawn, job,
"package\tinstalled\tgnome-power-manager;0.0.1;i386;data\tMore useless software", NULL);
g_assert_true (ret);
ret = pk_backend_unload (backend);
g_assert_true (ret);
g_object_unref (backend_spawn);
backend_spawn = pk_backend_spawn_new (conf);
ret = pk_backend_spawn_set_name (backend_spawn, "test_spawn");
g_assert_true (ret);
pk_backend_job_set_vfunc (job,
PK_BACKEND_SIGNAL_FINISHED,
PK_BACKEND_JOB_VFUNC (pk_test_backend_spawn_finished_cb),
backend_spawn);
pk_backend_job_set_vfunc (job,
PK_BACKEND_SIGNAL_PACKAGE,
PK_BACKEND_JOB_VFUNC (pk_test_backend_spawn_package_cb),
backend_spawn);
pk_backend_job_set_vfunc (job,
PK_BACKEND_SIGNAL_PACKAGES,
PK_BACKEND_JOB_VFUNC (pk_test_backend_spawn_packages_cb),
backend_spawn);
ret = pk_backend_spawn_helper (backend_spawn, job, "search-name.sh", "none", "bar", NULL);
g_assert_true (ret);
_g_test_loop_run_with_timeout (10000);
g_assert_cmpint (_backend_spawn_number_packages, ==, 2);
ret = pk_backend_unload (backend);
g_assert_true (ret);
g_object_unref (backend_spawn);
}
static void
pk_test_dbus_func (void)
{
g_autoptr(PkDbus) dbus = NULL;
dbus = pk_dbus_new ();
g_assert_true (dbus != NULL);
}
PkSpawnExitType mexit = PK_SPAWN_EXIT_TYPE_UNKNOWN;
guint stdout_count = 0;
guint finished_count = 0;
static void
pk_test_exit_cb (PkSpawn *spawn, PkSpawnExitType exit, gpointer user_data)
{
g_debug ("spawn exit=%i", exit);
mexit = exit;
finished_count++;
_g_test_loop_quit ();
}
static void
pk_test_stdout_cb (PkSpawn *spawn, const gchar *line, gpointer user_data)
{
g_debug ("stdout '%s'", line);
stdout_count++;
}
static gboolean
cancel_cb (gpointer data)
{
PkSpawn *spawn = PK_SPAWN(data);
pk_spawn_kill (spawn);
return FALSE;
}
static void
new_spawn_object (PkSpawn **pspawn)
{
g_autoptr(GKeyFile) conf = NULL;
if (*pspawn != NULL)
g_object_unref (*pspawn);
conf = g_key_file_new ();
*pspawn = pk_spawn_new (conf);
g_signal_connect (*pspawn, "exit",
G_CALLBACK (pk_test_exit_cb), NULL);
g_signal_connect (*pspawn, "stdout",
G_CALLBACK (pk_test_stdout_cb), NULL);
stdout_count = 0;
}
static gboolean
idle_cb (gpointer user_data)
{
g_assert_cmpint (mexit, ==, PK_SPAWN_EXIT_TYPE_DISPATCHER_EXIT);
return FALSE;
}
static void
pk_test_spawn_func (void)
{
GError *error = NULL;
gboolean ret;
g_autoptr(PkSpawn) spawn = NULL;
g_auto(GStrv) argv = NULL;
g_auto(GStrv) envp = NULL;
new_spawn_object (&spawn);
mexit = PK_SPAWN_EXIT_TYPE_UNKNOWN;
argv = g_strsplit ("pk-spawn-test-xxx.sh", " ", 0);
ret = pk_spawn_argv (spawn, argv, NULL, PK_SPAWN_ARGV_FLAGS_NONE, &error);
g_assert_error (error, 1, 0);
g_strfreev (argv);
g_assert_true (!ret);
g_clear_error (&error);
g_assert_cmpint (mexit, ==, PK_SPAWN_EXIT_TYPE_UNKNOWN);
mexit = -1;
argv = g_strsplit (TESTDATADIR "/pk-spawn-test.sh", " ", 0);
ret = pk_spawn_argv (spawn, argv, NULL, PK_SPAWN_ARGV_FLAGS_NONE, &error);
g_assert_no_error (error);
g_assert_true (ret);
g_strfreev (argv);
_g_test_loop_run_with_timeout (10000);
g_assert_cmpint (mexit, ==, PK_SPAWN_EXIT_TYPE_SUCCESS);
g_assert_cmpint (finished_count, ==, 1);
g_assert_cmpint (stdout_count, ==, 4+11);
new_spawn_object (&spawn);
mexit = -1;
argv = g_strsplit (TESTDATADIR "/pk-spawn-proxy.sh", " ", 0);
envp = g_strsplit ("http_proxy=username:password@server:port "
"ftp_proxy=username:password@server:port", " ", 0);
ret = pk_spawn_argv (spawn, argv, envp, PK_SPAWN_ARGV_FLAGS_NONE, &error);
g_assert_no_error (error);
g_assert_true (ret);
g_strfreev (argv);
g_strfreev (envp);
_g_test_loop_run_with_timeout (10000);
new_spawn_object (&spawn);
mexit = PK_SPAWN_EXIT_TYPE_UNKNOWN;
argv = g_strsplit (TESTDATADIR "/pk-spawn-test.sh", " ", 0);
ret = pk_spawn_argv (spawn, argv, NULL, PK_SPAWN_ARGV_FLAGS_NONE, &error);
g_assert_no_error (error);
g_assert_true (ret);
g_strfreev (argv);
g_timeout_add_seconds (1, cancel_cb, spawn);
_g_test_loop_run_with_timeout (5000);
g_assert_cmpint (mexit, ==, PK_SPAWN_EXIT_TYPE_SIGKILL);
new_spawn_object (&spawn);
mexit = PK_SPAWN_EXIT_TYPE_UNKNOWN;
argv = g_strsplit (TESTDATADIR "/pk-spawn-test.sh", " ", 0);
g_object_set (spawn,
"allow-sigkill", FALSE,
NULL);
ret = pk_spawn_argv (spawn, argv, NULL, PK_SPAWN_ARGV_FLAGS_NONE, &error);
g_assert_no_error (error);
g_assert_true (ret);
g_strfreev (argv);
g_timeout_add_seconds (1, cancel_cb, spawn);
_g_test_loop_run_with_timeout (10000);
g_assert_cmpint (mexit, ==, PK_SPAWN_EXIT_TYPE_SIGQUIT);
new_spawn_object (&spawn);
mexit = PK_SPAWN_EXIT_TYPE_UNKNOWN;
argv = g_strsplit (TESTDATADIR "/pk-spawn-test-sigquit.py", " ", 0);
ret = pk_spawn_argv (spawn, argv, NULL, PK_SPAWN_ARGV_FLAGS_NONE, &error);
g_assert_no_error (error);
g_assert_true (ret);
g_strfreev (argv);
g_timeout_add (1000, cancel_cb, spawn);
_g_test_loop_run_with_timeout (2000);
g_assert_cmpint (mexit, ==, PK_SPAWN_EXIT_TYPE_SIGQUIT);
argv = g_strsplit (TESTDATADIR "/pk-spawn-test-profiling.sh", " ", 0);
ret = pk_spawn_argv (spawn, argv, NULL, PK_SPAWN_ARGV_FLAGS_NONE, &error);
g_assert_no_error (error);
g_assert_true (ret);
g_strfreev (argv);
new_spawn_object (&spawn);
mexit = PK_SPAWN_EXIT_TYPE_UNKNOWN;
argv = g_strsplit (TESTDATADIR "/pk-spawn-dispatcher.py\tsearch-name\tnone\tpower manager", "\t", 0);
envp = g_strsplit ("NETWORK=TRUE LANG=C BACKGROUND=TRUE INTERACTIVE=TRUE UID=500", " ", 0);
ret = pk_spawn_argv (spawn, argv, envp, PK_SPAWN_ARGV_FLAGS_NONE, &error);
g_assert_no_error (error);
g_assert_true (ret);
_g_test_loop_wait (4000);
g_assert_cmpint (stdout_count, ==, 2);
g_assert_true (pk_spawn_is_running (spawn));
ret = pk_spawn_argv (spawn, argv, envp, PK_SPAWN_ARGV_FLAGS_NONE, &error);
g_assert_no_error (error);
g_assert_true (ret);
_g_test_loop_wait (100);
g_assert_cmpint (stdout_count, ==, 4);
g_idle_add (idle_cb, NULL);
ret = pk_spawn_exit (spawn);
g_assert_true (ret);
ret = pk_spawn_exit (spawn);
g_assert_true (!ret);
_g_test_loop_wait (100);
g_assert_true (!pk_spawn_is_running (spawn));
g_assert_cmpint (mexit, ==, PK_SPAWN_EXIT_TYPE_DISPATCHER_EXIT);
ret = pk_spawn_exit (spawn);
g_assert_true (!ret);
}
static void
pk_test_transaction_func (void)
{
gboolean ret;
GError *error = NULL;
GDBusNodeInfo *introspection;
g_autoptr(PkTransaction) transaction = NULL;
g_autoptr(GKeyFile) conf = NULL;
introspection = pk_load_introspection (PK_DBUS_INTERFACE_TRANSACTION ".xml", NULL);
g_assert_true (introspection != NULL);
conf = g_key_file_new ();
transaction = pk_transaction_new (conf, introspection);
g_assert_true (transaction != NULL);
ret = pk_transaction_strvalidate ("richard$\xffhughes", &error);
g_assert_error (error, PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_INPUT_INVALID);
g_assert_true (!ret);
g_clear_error (&error);
ret = pk_transaction_strvalidate ("richardhughes", &error);
g_assert_no_error (error);
g_assert_true (ret);
g_clear_error (&error);
g_dbus_node_info_unref (introspection);
}
static void
pk_test_transaction_db_func (void)
{
guint value;
gchar *tid;
gboolean ret;
gdouble ms;
GError *error = NULL;
g_autoptr(PkTransactionDb) db = NULL;
g_autofree gchar *proxy_http = NULL;
g_autofree gchar *proxy_ftp = NULL;
#if PK_BUILD_LOCAL
ret = g_file_test ("./transactions.db", G_FILE_TEST_EXISTS);
if (ret) {
value = g_unlink ("./transactions.db");
g_assert_true (value == 0);
}
#endif
g_test_timer_start ();
db = pk_transaction_db_new ();
ret = pk_transaction_db_load (db, &error);
g_assert_no_error (error);
g_assert_true (ret);
ms = g_test_timer_elapsed ();
g_assert_cmpfloat (ms, <, 1.5);
g_object_unref (db);
g_test_timer_start ();
db = pk_transaction_db_new ();
ret = pk_transaction_db_load (db, &error);
g_assert_no_error (error);
g_assert_true (ret);
ms = g_test_timer_elapsed ();
g_assert_cmpfloat (ms, <, 0.1);
value = pk_transaction_db_action_time_since (db, PK_ROLE_ENUM_REFRESH_CACHE);
g_assert_cmpint (value, ==, G_MAXUINT);
g_test_timer_start ();
tid = pk_transaction_db_generate_id (db);
ms = g_test_timer_elapsed ();
g_assert_cmpfloat (ms, <, 0.002);
g_free (tid);
g_test_timer_start ();
tid = pk_transaction_db_generate_id (db);
ms = g_test_timer_elapsed ();
g_assert_cmpfloat (ms, <, 0.005);
g_free (tid);
ret = pk_transaction_db_action_time_reset (db, PK_ROLE_ENUM_REFRESH_CACHE);
g_assert_true (ret);
g_test_timer_start ();
_g_test_loop_wait (2000);
value = pk_transaction_db_action_time_since (db, PK_ROLE_ENUM_REFRESH_CACHE);
g_assert_cmpint (value, >, 1);
g_assert_cmpint (value, <=, 4);
ret = pk_transaction_db_set_proxy (db, 500, "session1",
"127.0.0.1:80",
NULL,
"127.0.0.1:21",
NULL,
NULL,
NULL);
g_assert_true (ret);
ret = pk_transaction_db_set_proxy (db, 500, "session1",
"127.0.0.1:80",
NULL,
"127.0.0.1:21",
NULL,
NULL,
NULL);
g_assert_true (ret);
ret = pk_transaction_db_get_proxy (db, 501, "session1",
&proxy_http,
NULL,
&proxy_ftp,
NULL,
NULL,
NULL);
g_assert_true (ret);
g_assert_cmpstr (proxy_http, ==, NULL);
g_assert_cmpstr (proxy_ftp, ==, NULL);
ret = pk_transaction_db_get_proxy (db, 500, "session2",
&proxy_http,
NULL,
&proxy_ftp,
NULL,
NULL,
NULL);
g_assert_true (ret);
g_assert_cmpstr (proxy_http, ==, NULL);
g_assert_cmpstr (proxy_ftp, ==, NULL);
ret = pk_transaction_db_get_proxy (db, 500, "session1",
&proxy_http,
NULL,
&proxy_ftp,
NULL,
NULL,
NULL);
g_assert_true (ret);
g_assert_cmpstr (proxy_http, ==, "127.0.0.1:80");
g_assert_cmpstr (proxy_ftp, ==, "127.0.0.1:21");
}
static PkTransactionDb *db = NULL;
static void
pk_test_scheduler_finished_cb (PkTransaction *transaction, const gchar *exit_text, guint time, gpointer user_data)
{
_g_test_loop_quit ();
}
static gchar *
pk_test_scheduler_create_transaction (PkScheduler *tlist)
{
gchar *tid;
gboolean ret;
GError *error = NULL;
tid = pk_transaction_db_generate_id (db);
ret = pk_scheduler_create (tlist, tid, ":org.freedesktop.PackageKit", &error);
g_assert_no_error (error);
g_assert_true (ret);
return tid;
}
static void
pk_test_scheduler_func (void)
{
gboolean ret;
gchar *tid;
guint size;
gchar **array;
PkTransaction *transaction;
GError *error = NULL;
g_autofree gchar *tid_item1 = NULL;
g_autofree gchar *tid_item2 = NULL;
g_autofree gchar *tid_item3 = NULL;
g_autoptr(GKeyFile) conf = NULL;
g_autoptr(PkBackend) backend = NULL;
g_autoptr(PkScheduler) tlist = NULL;
#if PK_BUILD_LOCAL
ret = g_file_test ("./transactions.db", G_FILE_TEST_EXISTS);
if (ret) {
g_debug ("Removing %s", "./transactions.db");
size = g_unlink ("./transactions.db");
g_assert_true (size == 0);
}
#endif
db = pk_transaction_db_new ();
ret = pk_transaction_db_load (db, &error);
g_assert_no_error (error);
g_assert_true (ret);
conf = g_key_file_new ();
backend = pk_backend_new (conf);
g_key_file_set_string (conf, "Daemon", "DefaultBackend", "dummy");
g_key_file_set_string (conf, "Daemon", "MaximumPackagesToProcess", "1000");
ret = pk_backend_load (backend, NULL);
g_assert_true (ret);
tlist = pk_scheduler_new (conf);
g_assert_true (tlist != NULL);
pk_scheduler_set_backend (tlist, backend);
tid = pk_transaction_db_generate_id (db);
g_assert_true (tid != NULL);
ret = pk_scheduler_create (tlist, tid, ":org.freedesktop.PackageKit", &error);
g_assert_no_error (error);
g_assert_true (ret);
transaction = pk_scheduler_get_transaction (tlist, tid);
g_assert_true (transaction != NULL);
g_assert_cmpint (pk_transaction_get_state (transaction), ==, PK_TRANSACTION_STATE_NEW);
size = pk_scheduler_get_size (tlist);
g_assert_cmpint (size, ==, 1);
array = pk_scheduler_get_array (tlist);
size = g_strv_length (array);
g_assert_cmpint (size, ==, 0);
g_strfreev (array);
ret = pk_scheduler_create (tlist, tid, ":org.freedesktop.PackageKit", &error);
g_assert_error (error, 1, 0);
g_assert_true (!ret);
g_clear_error (&error);
ret = pk_scheduler_remove (tlist, tid);
g_assert_true (ret);
size = pk_scheduler_get_size (tlist);
g_assert_cmpint (size, ==, 0);
g_free (tid);
tid = pk_transaction_db_generate_id (db);
ret = pk_scheduler_create (tlist, tid, ":org.freedesktop.PackageKit", &error);
g_assert_no_error (error);
g_assert_true (ret);
transaction = pk_scheduler_get_transaction (tlist, tid);
g_assert_true (transaction != NULL);
g_signal_connect (transaction, "finished",
G_CALLBACK (pk_test_scheduler_finished_cb), NULL);
pk_transaction_get_updates (transaction,
g_variant_new ("(t)",
pk_bitfield_value (PK_FILTER_ENUM_NONE)),
NULL);
transaction = pk_scheduler_get_transaction (tlist, tid);
g_assert_cmpint (pk_transaction_get_state (transaction), ==, PK_TRANSACTION_STATE_RUNNING);
ret = pk_scheduler_role_present (tlist, PK_ROLE_ENUM_GET_UPDATES);
g_assert_true (ret);
ret = pk_scheduler_role_present (tlist, PK_ROLE_ENUM_SEARCH_NAME);
g_assert_true (!ret);
size = pk_scheduler_get_size (tlist);
g_assert_cmpint (size, ==, 1);
array = pk_scheduler_get_array (tlist);
size = g_strv_length (array);
g_assert_cmpint (size, ==, 1);
g_strfreev (array);
_g_test_loop_run_with_timeout (2000);
size = pk_scheduler_get_size (tlist);
g_assert_cmpint (size, ==, 1);
array = pk_scheduler_get_array (tlist);
size = g_strv_length (array);
g_assert_cmpint (size, ==, 0);
g_strfreev (array);
ret = pk_scheduler_remove (tlist, tid);
g_assert_true (!ret);
_g_test_loop_wait (10000);
size = pk_scheduler_get_size (tlist);
g_assert_cmpint (size, ==, 0);
g_free (tid);
tid_item1 = pk_test_scheduler_create_transaction (tlist);
tid_item2 = pk_test_scheduler_create_transaction (tlist);
tid_item3 = pk_test_scheduler_create_transaction (tlist);
size = pk_scheduler_get_size (tlist);
g_assert_cmpint (size, ==, 3);
array = pk_scheduler_get_array (tlist);
size = g_strv_length (array);
g_assert_cmpint (size, ==, 0);
g_strfreev (array);
transaction = pk_scheduler_get_transaction (tlist, tid_item1);
g_signal_connect (transaction, "finished",
G_CALLBACK (pk_test_scheduler_finished_cb), NULL);
transaction = pk_scheduler_get_transaction (tlist, tid_item2);
g_signal_connect (transaction, "finished",
G_CALLBACK (pk_test_scheduler_finished_cb), NULL);
transaction = pk_scheduler_get_transaction (tlist, tid_item3);
g_signal_connect (transaction, "finished",
G_CALLBACK (pk_test_scheduler_finished_cb), NULL);
array = g_strsplit ("dave", " ", -1);
transaction = pk_scheduler_get_transaction (tlist, tid_item1);
pk_transaction_make_exclusive (transaction);
pk_transaction_search_details (transaction,
g_variant_new ("(t^as)",
pk_bitfield_value (PK_FILTER_ENUM_NONE),
array),
NULL);
g_strfreev (array);
array = g_strsplit ("power", " ", -1);
transaction = pk_scheduler_get_transaction (tlist, tid_item2);
pk_transaction_make_exclusive (transaction);
pk_transaction_search_names (transaction,
g_variant_new ("(t^as)",
pk_bitfield_value (PK_FILTER_ENUM_NONE),
array),
NULL);
g_strfreev (array);
array = g_strsplit ("paul", " ", -1);
transaction = pk_scheduler_get_transaction (tlist, tid_item3);
pk_transaction_make_exclusive (transaction);
pk_transaction_search_details (transaction,
g_variant_new ("(t^as)",
pk_bitfield_value (PK_FILTER_ENUM_NONE),
array),
NULL);
g_strfreev (array);
array = pk_scheduler_get_array (tlist);
size = g_strv_length (array);
g_assert_cmpint (size, ==, 3);
g_strfreev (array);
_g_test_loop_run_with_timeout (10000);
size = pk_scheduler_get_size (tlist);
g_assert_cmpint (size, ==, 3);
array = pk_scheduler_get_array (tlist);
size = g_strv_length (array);
g_assert_cmpint (size, ==, 2);
g_strfreev (array);
transaction = pk_scheduler_get_transaction (tlist, tid_item1);
g_assert_cmpint (pk_transaction_get_state (transaction), ==, PK_TRANSACTION_STATE_FINISHED);
transaction = pk_scheduler_get_transaction (tlist, tid_item2);
g_assert_cmpint (pk_transaction_get_state (transaction), ==, PK_TRANSACTION_STATE_RUNNING);
transaction = pk_scheduler_get_transaction (tlist, tid_item3);
g_assert_cmpint (pk_transaction_get_state (transaction), ==, PK_TRANSACTION_STATE_READY);
_g_test_loop_run_with_timeout (10000);
size = pk_scheduler_get_size (tlist);
g_assert_cmpint (size, ==, 3);
array = pk_scheduler_get_array (tlist);
size = g_strv_length (array);
g_assert_cmpint (size, ==, 1);
g_strfreev (array);
transaction = pk_scheduler_get_transaction (tlist, tid_item1);
g_assert_cmpint (pk_transaction_get_state (transaction), ==, PK_TRANSACTION_STATE_FINISHED);
transaction = pk_scheduler_get_transaction (tlist, tid_item2);
g_assert_cmpint (pk_transaction_get_state (transaction), ==, PK_TRANSACTION_STATE_FINISHED);
transaction = pk_scheduler_get_transaction (tlist, tid_item3);
g_assert_cmpint (pk_transaction_get_state (transaction), ==, PK_TRANSACTION_STATE_RUNNING);
_g_test_loop_run_with_timeout (10000);
size = pk_scheduler_get_size (tlist);
g_assert_cmpint (size, ==, 3);
array = pk_scheduler_get_array (tlist);
size = g_strv_length (array);
g_assert_cmpint (size, ==, 0);
g_strfreev (array);
transaction = pk_scheduler_get_transaction (tlist, tid_item1);
g_assert_cmpint (pk_transaction_get_state (transaction), ==, PK_TRANSACTION_STATE_FINISHED);
transaction = pk_scheduler_get_transaction (tlist, tid_item2);
g_assert_cmpint (pk_transaction_get_state (transaction), ==, PK_TRANSACTION_STATE_FINISHED);
transaction = pk_scheduler_get_transaction (tlist, tid_item3);
g_assert_cmpint (pk_transaction_get_state (transaction), ==, PK_TRANSACTION_STATE_FINISHED);
_g_test_loop_wait (10000);
size = pk_scheduler_get_size (tlist);
g_assert_cmpint (size, <, 3);
array = pk_scheduler_get_array (tlist);
size = g_strv_length (array);
g_assert_cmpint (size, ==, 0);
g_strfreev (array);
g_object_unref (db);
}
static void
pk_test_scheduler_parallel_func (void)
{
guint size;
gboolean ret;
guint i;
gchar **array;
PkTransaction *transaction1;
PkTransaction *transaction2;
PkTransaction *transaction3;
GError *error = NULL;
g_autofree gchar *tid_item1 = NULL;
g_autofree gchar *tid_item2 = NULL;
g_autofree gchar *tid_item3 = NULL;
g_autofree gchar *tid_item4 = NULL;
g_autofree gchar *tid_item5 = NULL;
g_autoptr(GKeyFile) conf = NULL;
g_autoptr(PkBackend) backend = NULL;
g_autoptr(PkScheduler) tlist = NULL;
db = pk_transaction_db_new ();
ret = pk_transaction_db_load (db, &error);
g_assert_no_error (error);
g_assert_true (ret);
conf = g_key_file_new ();
g_key_file_set_string (conf, "Daemon", "MaximumPackagesToProcess", "1000");
g_key_file_set_string (conf, "Daemon", "DefaultBackend", "dummy");
backend = pk_backend_new (conf);
ret = pk_backend_load (backend, NULL);
g_assert_true (ret);
tlist = pk_scheduler_new (conf);
g_assert_true (tlist != NULL);
pk_scheduler_set_backend (tlist, backend);
tid_item1 = pk_test_scheduler_create_transaction (tlist);
tid_item2 = pk_test_scheduler_create_transaction (tlist);
tid_item3 = pk_test_scheduler_create_transaction (tlist);
tid_item4 = pk_test_scheduler_create_transaction (tlist);
tid_item5 = pk_test_scheduler_create_transaction (tlist);
size = pk_scheduler_get_size (tlist);
g_assert_cmpint (size, ==, 5);
array = pk_scheduler_get_array (tlist);
size = g_strv_length (array);
g_assert_cmpint (size, ==, 0);
g_strfreev (array);
transaction1 = pk_scheduler_get_transaction (tlist, tid_item1);
g_signal_connect (transaction1, "finished",
G_CALLBACK (pk_test_scheduler_finished_cb), NULL);
transaction1 = pk_scheduler_get_transaction (tlist, tid_item2);
g_signal_connect (transaction1, "finished",
G_CALLBACK (pk_test_scheduler_finished_cb), NULL);
transaction1 = pk_scheduler_get_transaction (tlist, tid_item3);
g_signal_connect (transaction1, "finished",
G_CALLBACK (pk_test_scheduler_finished_cb), NULL);
transaction1 = pk_scheduler_get_transaction (tlist, tid_item4);
g_signal_connect (transaction1, "finished",
G_CALLBACK (pk_test_scheduler_finished_cb), NULL);
transaction1 = pk_scheduler_get_transaction (tlist, tid_item5);
g_signal_connect (transaction1, "finished",
G_CALLBACK (pk_test_scheduler_finished_cb), NULL);
array = g_strsplit ("dave", " ", -1);
transaction1 = pk_scheduler_get_transaction (tlist, tid_item1);
pk_transaction_search_details (transaction1,
g_variant_new ("(t^as)",
pk_bitfield_value (PK_FILTER_ENUM_NONE),
array),
NULL);
g_strfreev (array);
array = g_strsplit ("libawesome;42;i386;debian", " ", -1);
transaction1 = pk_scheduler_get_transaction (tlist, tid_item2);
pk_transaction_skip_auth_checks (transaction1, TRUE);
pk_transaction_install_packages (transaction1,
g_variant_new ("(t^as)",
pk_bitfield_value (PK_FILTER_ENUM_NONE),
array),
NULL);
g_strfreev (array);
array = g_strsplit ("power", " ", -1);
transaction1 = pk_scheduler_get_transaction (tlist, tid_item3);
pk_transaction_search_names (transaction1,
g_variant_new ("(t^as)",
pk_bitfield_value (PK_FILTER_ENUM_NONE),
array),
NULL);
g_strfreev (array);
array = g_strsplit ("foobar;1.1.0;i386;debian", " ", -1);
transaction1 = pk_scheduler_get_transaction (tlist, tid_item4);
pk_transaction_skip_auth_checks (transaction1, TRUE);
pk_transaction_install_packages (transaction1,
g_variant_new ("(t^as)",
pk_bitfield_value (PK_FILTER_ENUM_NONE),
array),
NULL);
g_strfreev (array);
array = pk_scheduler_get_array (tlist);
size = g_strv_length (array);
g_assert_cmpint (size, ==, 4);
g_strfreev (array);
_g_test_loop_run_with_timeout (10000);
transaction1 = pk_scheduler_get_transaction (tlist, tid_item4);
g_assert_cmpint (pk_transaction_get_state (transaction1), ==, PK_TRANSACTION_STATE_READY);
transaction1 = pk_scheduler_get_transaction (tlist, tid_item3);
g_assert_cmpint (pk_transaction_get_state (transaction1), ==, PK_TRANSACTION_STATE_RUNNING);
transaction1 = pk_scheduler_get_transaction (tlist, tid_item2);
g_assert_cmpint (pk_transaction_get_state (transaction1), ==, PK_TRANSACTION_STATE_RUNNING);
array = g_strsplit ("paul", " ", -1);
transaction1 = pk_scheduler_get_transaction (tlist, tid_item5);
pk_transaction_search_details (transaction1,
g_variant_new ("(t^as)",
pk_bitfield_value (PK_FILTER_ENUM_NONE),
array),
NULL);
g_strfreev (array);
size = pk_scheduler_get_size (tlist);
g_assert_cmpint (size, ==, 5);
i = 0;
while (TRUE) {
_g_test_loop_run_with_timeout (10000 - i * 20);
i++;
transaction1 = pk_scheduler_get_transaction (tlist, tid_item1);
transaction2 = pk_scheduler_get_transaction (tlist, tid_item3);
transaction3 = pk_scheduler_get_transaction (tlist, tid_item5);
if (i >= 100 ||
transaction1 == NULL ||
transaction2 == NULL ||
transaction3 == NULL) {
g_print ("Dumping scheduler state:\n%s\n", pk_scheduler_get_state (tlist));
g_warning ("did not reach state where all non-exclusive transactions are finished");
g_assert_not_reached ();
}
if (pk_transaction_get_state (transaction1) == PK_TRANSACTION_STATE_FINISHED &&
pk_transaction_get_state (transaction2) == PK_TRANSACTION_STATE_FINISHED &&
pk_transaction_get_state (transaction3) == PK_TRANSACTION_STATE_FINISHED)
break;
}
array = pk_scheduler_get_array (tlist);
size = g_strv_length (array);
g_assert_cmpint (size, ==, 2);
g_strfreev (array);
_g_test_loop_run_with_timeout (10000);
transaction1 = pk_scheduler_get_transaction (tlist, tid_item2);
g_assert_cmpint (pk_transaction_get_state (transaction1), ==, PK_TRANSACTION_STATE_FINISHED);
transaction1 = pk_scheduler_get_transaction (tlist, tid_item4);
g_assert_cmpint (pk_transaction_get_state (transaction1), ==, PK_TRANSACTION_STATE_RUNNING);
_g_test_loop_run_with_timeout (20000);
transaction1 = pk_scheduler_get_transaction (tlist, tid_item4);
g_assert_cmpint (pk_transaction_get_state (transaction1), ==, PK_TRANSACTION_STATE_FINISHED);
array = pk_scheduler_get_array (tlist);
size = g_strv_length (array);
g_assert_cmpint (size, ==, 0);
g_strfreev (array);
g_object_unref (db);
}
int
main (int argc, char **argv)
{
g_test_init (&argc, &argv, NULL);
#ifndef PK_ENABLE_DAEMON_TESTS
return 0;
#endif
#ifndef PK_BUILD_LOCAL
g_warning ("you need to compile with -Dlocal_checkout=true for ninja test support");
#endif
g_test_add_func ("/packagekit/transaction", pk_test_transaction_func);
g_test_add_func ("/packagekit/dbus", pk_test_dbus_func);
g_test_add_func ("/packagekit/spawn", pk_test_spawn_func);
g_test_add_func ("/packagekit/scheduler", pk_test_scheduler_func);
g_test_add_func ("/packagekit/scheduler-parallel", pk_test_scheduler_parallel_func);
g_test_add_func ("/packagekit/transaction-db", pk_test_transaction_db_func);
g_test_add_func ("/packagekit/backend", pk_test_backend_func);
g_test_add_func ("/packagekit/backend_spawn", pk_test_backend_spawn_func);
return g_test_run ();
}