/* * Copyright (C) 2016 J. Ali Harlow * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include #include #include #include #include #include GtkBuilder *ui; gboolean manual_mode=FALSE; PloverTransactionHelper *get_transaction_helper(void) { const char *dir; gchar *s; GError *err=NULL; PloverTransactionHelper *helper; dir=g_getenv("gtk_srcdir"); s=g_build_filename(dir,"software-installation.ui",NULL); ui=gtk_builder_new(); if (!gtk_builder_add_from_file(ui,s,&err)) g_error("%s: %s",s,err->message); g_free(s); helper=plover_transaction_helper_new(ui); g_object_unref(ui); return helper; } static void test_init(void) { PloverTransactionHelper *helper; helper=get_transaction_helper(); g_object_unref(helper); } static void test_basic_properties(void) { const char *prefix; GError *err=NULL; struct comps *comps; PloverTransactionHelper *helper; PloverPackageSet *installed; PloverRepository *upstream; upstream=plover_repository_new_from_yum("../yum-repo-test-dir",&err); if (!upstream) g_error("../yum-repo-test-dir: %s",err->message); installed=plover_package_set_new_from_installed("../razor-test-dir",&err); if (!installed) g_error("../razor-test-dir: %s",err->message); helper=get_transaction_helper(); g_assert(!plover_transaction_helper_get_visible(helper)); plover_transaction_helper_set_installed(helper,installed); g_assert(plover_transaction_helper_get_installed(helper)==installed); plover_transaction_helper_set_upstream(helper,upstream); g_assert(plover_transaction_helper_get_upstream(helper,&err)==upstream); g_assert(!err); plover_transaction_helper_set_base(helper,"../yum-repo-test-dir"); g_assert_cmpstr(plover_transaction_helper_get_base(helper),==,"../yum-repo-test-dir"); comps=plover_transaction_helper_get_comps(helper,&err); g_assert(!err); g_assert(plover_comps_lookup_group(comps,"base")); prefix=plover_transaction_helper_get_prefix(helper,&err); g_assert(!err); g_assert_cmpstr(prefix,==,plover_default_prefix_for_vendor("Acme Corporation")); g_assert(!plover_transaction_helper_get_visible(helper)); g_assert(!plover_transaction_helper_get_error(helper,NULL)); g_object_unref(upstream); g_object_unref(installed); g_object_unref(helper); } static void test_install_group(void) { gchar *root; GError *err=NULL; PloverPackageSet *installed; PloverTransactionHelper *helper; root=g_strdup("razor-test-dir-XXXXXX"); g_assert(mkdtemp(root)); g_setenv("RAZOR_ROOT",root,TRUE); g_free(root); helper=get_transaction_helper(); installed=plover_package_set_new_from_installed("../razor-test-dir",&err); if (!installed) g_error("../razor-test-dir: %s",err->message); plover_transaction_helper_set_installed(helper,installed); g_object_unref(installed); plover_transaction_helper_set_base(helper,"../yum-repo-test-dir"); if (!plover_transaction_helper_install_group(helper,"base",&err)) g_error("base: %s",err->message); g_assert(!err); g_object_unref(helper); g_unsetenv("RAZOR_ROOT"); } static void test_remove_group(void) { gchar *root; GError *err=NULL; PloverPackageSet *installed; PloverTransactionHelper *helper; struct plover_vector *packages; char *pkgs[]={"zip",NULL}; root=g_strdup("razor-test-dir-XXXXXX"); g_assert(mkdtemp(root)); g_setenv("RAZOR_ROOT",root,TRUE); helper=get_transaction_helper(); plover_transaction_helper_set_base(helper,"../yum-repo-test-dir"); packages=plover_transaction_helper_group_get_default_packages(helper, "zappy",&err); if (!packages) g_error("zappy: %s",err->message); if (!plover_install("../yum-repo-test-dir",NULL,packages->strings,&err)) g_error("plover_install: %s",err->message); plover_vector_free(packages); installed=plover_package_set_new_from_installed(root,&err); if (!installed) g_error("%s: %s",root,err->message); plover_transaction_helper_set_installed(helper,installed); g_object_unref(installed); if (!plover_transaction_helper_remove_group(helper,"zappy",&err)) g_error("zappy: %s",err->message); g_assert(!err); g_object_unref(helper); g_unsetenv("RAZOR_ROOT"); g_free(root); } static void test_update(void) { gchar *root; GError *err=NULL; PloverPackageSet *installed; PloverTransactionHelper *helper; root=g_strdup("razor-test-dir-XXXXXX"); g_assert(mkdtemp(root)); g_setenv("RAZOR_ROOT",root,TRUE); g_free(root); helper=get_transaction_helper(); installed=plover_package_set_new_from_installed("../razor-test-dir",&err); if (!installed) g_error("../razor-test-dir: %s",err->message); plover_transaction_helper_set_installed(helper,installed); g_object_unref(installed); plover_transaction_helper_set_base(helper,"../yum-repo-test-dir"); if (plover_transaction_helper_update(helper,&err)) g_error("plover_transaction_helper_update reports work to be done"); g_assert_error(err,PLOVER_GENERAL_ERROR,PLOVER_GENERAL_ERROR_NO_WORK); g_object_unref(helper); g_unsetenv("RAZOR_ROOT"); } struct run_install_baton { enum { RI_STATE_INIT = 0, RI_STATE_SUMMARY, RI_STATE_PROGRESS, RI_STATE_PROGRESS_DELAY, RI_STATE_DONE, RI_STATE_FINISH } state; guint eid; /* event ID (or 0) */ PloverTransactionHelper *helper; }; gboolean run_install_tick(gpointer data) { gboolean retval=TRUE; struct run_install_baton *baton=data; GtkWidget *page; GtkAssistant *assistant=baton->helper->assistant; switch(baton->state) { case RI_STATE_INIT: if (!assistant || !gtk_widget_get_visible(GTK_WIDGET(assistant))) return TRUE; if (!manual_mode) gtk_button_clicked(GTK_BUTTON(assistant->forward)); break; case RI_STATE_SUMMARY: if (gtk_assistant_get_current_page(assistant)<1) return TRUE; if (!manual_mode) gtk_button_clicked(GTK_BUTTON(assistant->apply)); break; case RI_STATE_PROGRESS: if (gtk_assistant_get_current_page(assistant)<2) return TRUE; page=gtk_assistant_get_nth_page(assistant,2); baton->eid=g_timeout_add_seconds(1,run_install_tick,baton); if (!gtk_assistant_get_page_complete(assistant,page)) return FALSE; else retval=FALSE; break; case RI_STATE_PROGRESS_DELAY: retval=FALSE; baton->eid=g_idle_add_full(G_PRIORITY_LOW,run_install_tick,baton, NULL); if (!manual_mode) gtk_button_clicked(GTK_BUTTON(assistant->forward)); break; case RI_STATE_DONE: if (gtk_assistant_get_current_page(assistant)<3) return TRUE; if (!manual_mode) gtk_button_clicked(GTK_BUTTON(assistant->close)); break; case RI_STATE_FINISH: if (assistant && gtk_widget_get_visible(GTK_WIDGET(assistant))) return TRUE; gtk_main_quit(); baton->eid=0; return FALSE; } baton->state++; return retval; } static void test_run_install(void) { gchar *root; GError *err=NULL; struct plover_vector *packages; PloverPackageSet *installed; PloverTransactionHelper *helper; struct run_install_baton baton={0,}; root=g_strdup("razor-test-dir-XXXXXX"); g_assert(mkdtemp(root)); g_setenv("RAZOR_ROOT",root,TRUE); helper=get_transaction_helper(); installed=plover_package_set_new(); if (!plover_package_set_open(installed,root,TRUE,&err)) g_error("%s: %s",root,err->message); plover_transaction_helper_set_installed(helper,installed); g_object_unref(installed); plover_transaction_helper_set_base(helper,"../yum-repo-test-dir"); packages=plover_vector_new(); plover_vector_append(packages,"zappy-tools"); if (!plover_transaction_helper_install_packages(helper,packages,&err)) g_error("zappy-tools: %s",err->message); g_assert(!err); plover_vector_free(packages); plover_transaction_helper_present(helper); baton.helper=helper; baton.eid=g_idle_add_full(G_PRIORITY_LOW,run_install_tick,&baton,NULL); gtk_main(); g_object_unref(helper); g_unsetenv("RAZOR_ROOT"); g_free(root); } struct run_remove_baton { enum { RR_STATE_INIT = 0, RR_STATE_SUMMARY, RR_STATE_PROGRESS, RR_STATE_PROGRESS_DELAY, RR_STATE_DONE, RR_STATE_FINISH } state; guint eid; /* event ID (or 0) */ PloverTransactionHelper *helper; }; gboolean run_remove_tick(gpointer data) { gboolean retval=TRUE; struct run_remove_baton *baton=data; GtkWidget *page; GtkAssistant *assistant=baton->helper->assistant; switch(baton->state) { case RR_STATE_INIT: if (!assistant || !gtk_widget_get_visible(GTK_WIDGET(assistant))) return TRUE; if (!manual_mode) gtk_button_clicked(GTK_BUTTON(assistant->forward)); break; case RR_STATE_SUMMARY: if (gtk_assistant_get_current_page(assistant)<1) return TRUE; if (!manual_mode) gtk_button_clicked(GTK_BUTTON(assistant->apply)); break; case RR_STATE_PROGRESS: if (gtk_assistant_get_current_page(assistant)<2) return TRUE; page=gtk_assistant_get_nth_page(assistant,2); baton->eid=g_timeout_add_seconds(1,run_remove_tick,baton); if (!gtk_assistant_get_page_complete(assistant,page)) return FALSE; else retval=FALSE; break; case RR_STATE_PROGRESS_DELAY: retval=FALSE; baton->eid=g_idle_add_full(G_PRIORITY_LOW,run_remove_tick,baton, NULL); if (!manual_mode) gtk_button_clicked(GTK_BUTTON(assistant->forward)); break; case RR_STATE_DONE: if (gtk_assistant_get_current_page(assistant)<3) return TRUE; if (!manual_mode) gtk_button_clicked(GTK_BUTTON(assistant->close)); break; case RR_STATE_FINISH: if (assistant && gtk_widget_get_visible(GTK_WIDGET(assistant))) return TRUE; gtk_main_quit(); baton->eid=0; return FALSE; } baton->state++; return retval; } static void test_run_remove(void) { gchar *root; GError *err=NULL; struct plover_vector *packages; PloverPackageSet *installed; PloverTransactionHelper *helper; struct run_remove_baton baton={0,}; root=g_strdup("razor-test-dir-XXXXXX"); g_assert(mkdtemp(root)); g_setenv("RAZOR_ROOT",root,TRUE); helper=get_transaction_helper(); plover_transaction_helper_set_base(helper,"../yum-repo-test-dir"); packages= plover_transaction_helper_group_get_default_packages(helper,"zappy",&err); if (!packages) g_error("zappy: %s",err->message); if (!plover_install("../yum-repo-test-dir",NULL,packages->strings,&err)) g_error("plover_install: %s",err->message); plover_vector_free(packages); installed=plover_package_set_new(); if (!plover_package_set_open(installed,root,TRUE,&err)) g_error("%s: %s",root,err->message); plover_transaction_helper_set_installed(helper,installed); g_object_unref(installed); if (!plover_transaction_helper_remove_group(helper,"zappy",&err)) g_error("zappy: %s",err->message); g_assert(!err); plover_transaction_helper_present(helper); baton.helper=helper; baton.eid=g_idle_add_full(G_PRIORITY_LOW,run_remove_tick,&baton,NULL); gtk_main(); g_object_unref(helper); g_unsetenv("RAZOR_ROOT"); g_free(root); } struct run_update_baton { enum { RU_STATE_INIT = 0, RU_STATE_SUMMARY, RU_STATE_PROGRESS, RU_STATE_PROGRESS_DELAY, RU_STATE_DONE, RU_STATE_FINISH } state; guint eid; /* event ID (or 0) */ PloverTransactionHelper *helper; }; gboolean run_update_tick(gpointer data) { gboolean retval=TRUE; struct run_update_baton *baton=data; GtkWidget *page; GtkAssistant *assistant=baton->helper->assistant; switch(baton->state) { case RU_STATE_INIT: if (!assistant || !gtk_widget_get_visible(GTK_WIDGET(assistant))) return TRUE; if (!manual_mode) gtk_button_clicked(GTK_BUTTON(assistant->forward)); break; case RU_STATE_SUMMARY: if (gtk_assistant_get_current_page(assistant)<1) return TRUE; if (!manual_mode) gtk_button_clicked(GTK_BUTTON(assistant->apply)); break; case RU_STATE_PROGRESS: if (gtk_assistant_get_current_page(assistant)<2) return TRUE; page=gtk_assistant_get_nth_page(assistant,2); baton->eid=g_timeout_add_seconds(1,run_update_tick,baton); if (!gtk_assistant_get_page_complete(assistant,page)) return FALSE; else retval=FALSE; break; case RU_STATE_PROGRESS_DELAY: retval=FALSE; baton->eid=g_idle_add_full(G_PRIORITY_LOW,run_update_tick,baton, NULL); if (!manual_mode) gtk_button_clicked(GTK_BUTTON(assistant->forward)); break; case RU_STATE_DONE: if (gtk_assistant_get_current_page(assistant)<3) return TRUE; if (!manual_mode) gtk_button_clicked(GTK_BUTTON(assistant->close)); break; case RU_STATE_FINISH: if (assistant && gtk_widget_get_visible(GTK_WIDGET(assistant))) return TRUE; gtk_main_quit(); baton->eid=0; return FALSE; } baton->state++; return retval; } static void test_run_update(void) { gchar *root; GError *err=NULL; struct razor_importer *importer; struct razor_set *downgraded; struct razor_atomic *atomic; struct plover_vector *packages; PloverPackageSet *installed; PloverTransactionHelper *helper; struct run_update_baton baton={0,}; root=g_strdup("razor-test-dir-XXXXXX"); g_assert(mkdtemp(root)); g_setenv("RAZOR_ROOT",root,TRUE); helper=get_transaction_helper(); plover_transaction_helper_set_base(helper,"../yum-repo-test-dir"); installed=plover_package_set_new(); if (!plover_package_set_open(installed,root,TRUE,&err)) g_error("%s: %s",root,err->message); importer=razor_importer_create(); razor_importer_begin_package(importer,"zappy","0-1","noarch"); razor_importer_add_details(importer,"","","",""); razor_importer_add_property(importer,"zappy",RAZOR_PROPERTY_PROVIDES,"0-1"); razor_importer_finish_package(importer); downgraded=razor_importer_finish(importer); atomic=razor_atomic_open("Add downgraded packages"); if (!plover_package_set_update(installed,downgraded,atomic) || razor_atomic_commit(atomic)) g_error("%s: %s",root,razor_atomic_get_error_msg(atomic)); razor_atomic_destroy(atomic); razor_set_unref(downgraded); plover_transaction_helper_set_installed(helper,installed); g_object_unref(installed); if (!plover_transaction_helper_update(helper,&err)) g_error("update: %s",err->message); g_assert(!err); plover_transaction_helper_present(helper); baton.helper=helper; baton.eid=g_idle_add_full(G_PRIORITY_LOW,run_update_tick,&baton,NULL); gtk_main(); g_object_unref(helper); g_unsetenv("RAZOR_ROOT"); g_free(root); } struct check_vendor_baton { enum { CV_STATE_INIT = 0, CV_STATE_SUMMARY, CV_STATE_PROGRESS, CV_STATE_PROGRESS_DELAY, CV_STATE_DONE, CV_STATE_FINISH } state; guint eid; /* event ID (or 0) */ PloverTransactionHelper *helper; }; gboolean check_vendor_tick(gpointer data) { gboolean retval=TRUE; struct check_vendor_baton *baton=data; GtkWidget *page,*w; GtkAssistant *assistant=baton->helper->assistant; switch(baton->state) { case CV_STATE_INIT: if (!assistant || !gtk_widget_get_visible(GTK_WIDGET(assistant))) return TRUE; if (!manual_mode) gtk_button_clicked(GTK_BUTTON(assistant->forward)); break; case CV_STATE_SUMMARY: if (gtk_assistant_get_current_page(assistant)<1) return TRUE; g_assert(!gtk_widget_is_sensitive(assistant->apply)); w=GTK_WIDGET(gtk_builder_get_object(ui,"SIRemoveExisting")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w),TRUE); g_assert(gtk_widget_is_sensitive(assistant->apply)); if (!manual_mode) gtk_button_clicked(GTK_BUTTON(assistant->apply)); break; case CV_STATE_PROGRESS: if (gtk_assistant_get_current_page(assistant)<2) return TRUE; page=gtk_assistant_get_nth_page(assistant,2); baton->eid=g_timeout_add_seconds(1,check_vendor_tick,baton); if (!gtk_assistant_get_page_complete(assistant,page)) return FALSE; else retval=FALSE; break; case CV_STATE_PROGRESS_DELAY: retval=FALSE; baton->eid=g_idle_add_full(G_PRIORITY_LOW,check_vendor_tick,baton, NULL); if (!manual_mode) gtk_button_clicked(GTK_BUTTON(assistant->forward)); break; case CV_STATE_DONE: if (gtk_assistant_get_current_page(assistant)<3) return TRUE; if (!manual_mode) gtk_button_clicked(GTK_BUTTON(assistant->close)); break; case CV_STATE_FINISH: if (assistant && gtk_widget_get_visible(GTK_WIDGET(assistant))) return TRUE; gtk_main_quit(); baton->eid=0; return FALSE; } baton->state++; return retval; } static void test_check_vendor(void) { int fh; gchar *root,*s; GError *err=NULL; struct razor_importer *importer; struct razor_set *downgraded; struct razor_atomic *atomic; struct plover_vector *packages; PloverPackageSet *installed; PloverTransactionHelper *helper; struct run_update_baton baton={0,}; g_setenv("PLOVER_VENDOR_PREFIX","/srv",TRUE); root=g_strdup("razor-test-dir-XXXXXX"); g_assert(mkdtemp(root)); g_setenv("RAZOR_ROOT",root,TRUE); helper=get_transaction_helper(); plover_transaction_helper_set_check_vendor(helper,TRUE); plover_transaction_helper_set_base(helper,"../yum-repo-test-dir"); installed=plover_package_set_new(); if (!plover_package_set_open(installed,root,TRUE,&err)) g_error("%s: %s",root,err->message); importer=razor_importer_create(); razor_importer_begin_package(importer,"zappy","0-1","noarch"); razor_importer_add_details(importer,"","","",""); razor_importer_add_property(importer,"zappy",RAZOR_PROPERTY_PROVIDES,"0-1"); razor_importer_add_install_prefix(importer,"/test"); razor_importer_add_file(importer,"/test/bin/zappy"); razor_importer_finish_package(importer); downgraded=razor_importer_finish(importer); atomic=razor_atomic_open("Add downgraded packages"); razor_atomic_make_dirs(atomic,root,"/test/bin/zappy"); s=g_build_filename(root,"test/bin/zappy",NULL); fh=razor_atomic_create_file(atomic,s,S_IRWXU|S_IRWXG|S_IRWXO); g_free(s); razor_atomic_close(atomic,fh); if (!plover_package_set_update(installed,downgraded,atomic) || razor_atomic_commit(atomic)) g_error("%s: %s",root,razor_atomic_get_error_msg(atomic)); razor_atomic_destroy(atomic); razor_set_unref(downgraded); plover_transaction_helper_set_installed(helper,installed); g_object_unref(installed); if (!plover_transaction_helper_update(helper,&err)) g_error("update: %s",err->message); g_assert(!err); plover_transaction_helper_present(helper); baton.helper=helper; baton.eid=g_idle_add_full(G_PRIORITY_LOW,check_vendor_tick,&baton,NULL); gtk_main(); g_object_unref(helper); g_unsetenv("RAZOR_ROOT"); g_free(root); g_unsetenv("PLOVER_VENDOR_PREFIX"); } struct set_error_baton { enum { SE_STATE_INIT = 0, SE_STATE_FINISH } state; PloverTransactionHelper *helper; }; /* * This handler may be called as either an event (ie., idle or timeout) * or as a (swapped) signal. In the latter case, the return is ignored. */ gboolean set_error_tick(gpointer data) { struct set_error_baton *baton=data; GtkDialog *dlg; GtkWidget *button; dlg=GTK_DIALOG(baton->helper->error_dialog); switch(baton->state) { case SE_STATE_INIT: if (!dlg || !gtk_widget_get_visible(GTK_WIDGET(dlg))) return TRUE; button=gtk_dialog_get_widget_for_response(dlg,GTK_RESPONSE_CLOSE); if (!manual_mode) gtk_button_clicked(GTK_BUTTON(button)); break; case SE_STATE_FINISH: if (dlg && gtk_widget_get_visible(GTK_WIDGET(dlg))) return TRUE; gtk_main_quit(); return FALSE; } baton->state++; return TRUE; } static void test_set_error(void) { gchar *root; const char *errmsg; GError *err=NULL; const GError *err2=NULL; PloverPackageSet *installed; PloverTransactionHelper *helper; struct set_error_baton baton={0,}; root=g_strdup("razor-test-dir-XXXXXX"); g_assert(mkdtemp(root)); g_setenv("RAZOR_ROOT",root,TRUE); g_free(root); helper=get_transaction_helper(); installed=plover_package_set_new_from_installed("../razor-test-dir",&err); if (!installed) g_error("../razor-test-dir: %s",err->message); plover_transaction_helper_set_installed(helper,installed); g_object_unref(installed); plover_transaction_helper_set_base(helper,"../yum-repo-test-dir"); if (!plover_transaction_helper_update(helper,&err)) plover_transaction_helper_set_error(helper,err,"Expected error"); g_assert(plover_transaction_helper_get_visible(helper)); errmsg=plover_transaction_helper_get_error(helper,&err2); g_assert_cmpstr(errmsg,==,"Expected error"); g_assert_error(err2,err->domain,err->code); plover_transaction_helper_present(helper); baton.helper=helper; g_idle_add_full(G_PRIORITY_LOW,set_error_tick,&baton,NULL); g_error_free(err); gtk_main(); g_object_unref(helper); g_unsetenv("RAZOR_ROOT"); } int main(int argc,char **argv) { int retval; GError *err=NULL; /* * Note that because g_test_init() handles --help, * these options will not appear in the output. */ GOptionEntry options[]={ {"manual",0,0,G_OPTION_ARG_NONE,&manual_mode, "Disable automatic mode",NULL}, {NULL} }; g_test_init(&argc,&argv,NULL); g_setenv("GTK_MODULES","",TRUE); g_setenv("GTK2_RC_FILES","/dev/null",TRUE); gtk_disable_setlocale(); setlocale(LC_ALL,"C"); g_test_bug_base("mailto:ali@juiblex.co.uk"); if (!gtk_init_with_args(&argc,&argv,NULL,options,NULL,&err)) { g_printf("%s\n",err->message); exit(0); } g_test_add_func("/transactionhelper/init",test_init); g_test_add_func("/transactionhelper/basic-properties", test_basic_properties); g_test_add_func("/transactionhelper/install-group",test_install_group); g_test_add_func("/transactionhelper/remove-group",test_remove_group); g_test_add_func("/transactionhelper/update",test_update); g_test_add_func("/transactionhelper/run-install",test_run_install); g_test_add_func("/transactionhelper/run-remove",test_run_remove); g_test_add_func("/transactionhelper/run-update",test_run_update); g_test_add_func("/transactionhelper/check-vendor",test_check_vendor); g_test_add_func("/transactionhelper/set-error",test_set_error); retval=g_test_run(); return retval; }