tests/plover-gtk/test-transactionhelper.c
author J. Ali Harlow <ali@juiblex.co.uk>
Mon Jun 13 12:19:50 2016 +0100 (2016-06-13)
changeset 40 e61a449e94cb
child 42 419a02fa70db
permissions -rw-r--r--
Added tag 0.5.2 for changeset 4af9b57a647f
     1 /*
     2  * Copyright (C) 2016  J. Ali Harlow <ali@juiblex.co.uk>
     3  *
     4  * This program is free software; you can redistribute it and/or modify
     5  * it under the terms of the GNU General Public License as published by
     6  * the Free Software Foundation; either version 2 of the License, or
     7  * (at your option) any later version.
     8  *
     9  * This program is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU General Public License along
    15  * with this program; if not, write to the Free Software Foundation, Inc.,
    16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
    17  */
    18 
    19 #include <stdlib.h>
    20 #include <string.h>
    21 #include <locale.h>
    22 #include <sys/stat.h>
    23 #include <glib.h>
    24 #include <gdk/gdk.h>
    25 #include <gtk/gtk.h>
    26 #include <plover/plover.h>
    27 #include <plover-gtk/transactionhelper.h>
    28 
    29 GtkBuilder *ui;
    30 gboolean manual_mode=FALSE;
    31 
    32 PloverTransactionHelper *get_transaction_helper(void)
    33 {
    34     const char *dir;
    35     gchar *s;
    36     GError *err=NULL;
    37     PloverTransactionHelper *helper;
    38     dir=g_getenv("gtk_srcdir");
    39     s=g_build_filename(dir,"software-installation.ui",NULL);
    40     ui=gtk_builder_new();
    41     if (!gtk_builder_add_from_file(ui,s,&err))
    42 	g_error("%s: %s",s,err->message);
    43     g_free(s);
    44     helper=plover_transaction_helper_new(ui);
    45     g_object_unref(ui);
    46     return helper;
    47 }
    48 
    49 static void test_init(void)
    50 {
    51     PloverTransactionHelper *helper;
    52     helper=get_transaction_helper();
    53     g_object_unref(helper);
    54 }
    55 
    56 static void test_basic_properties(void)
    57 {
    58     const char *prefix;
    59     GError *err=NULL;
    60     struct comps *comps;
    61     PloverTransactionHelper *helper;
    62     PloverPackageSet *installed;
    63     PloverRepository *upstream;
    64     upstream=plover_repository_new_from_yum("../yum-repo-test-dir",&err);
    65     if (!upstream)
    66 	g_error("../yum-repo-test-dir: %s",err->message);
    67     installed=plover_package_set_new_from_installed("../razor-test-dir",&err);
    68     if (!installed)
    69 	g_error("../razor-test-dir: %s",err->message);
    70     helper=get_transaction_helper();
    71     g_assert(!plover_transaction_helper_get_visible(helper));
    72     plover_transaction_helper_set_installed(helper,installed);
    73     g_assert(plover_transaction_helper_get_installed(helper)==installed);
    74     plover_transaction_helper_set_upstream(helper,upstream);
    75     g_assert(plover_transaction_helper_get_upstream(helper,&err)==upstream);
    76     g_assert(!err);
    77     plover_transaction_helper_set_base(helper,"../yum-repo-test-dir");
    78     g_assert_cmpstr(plover_transaction_helper_get_base(helper),==,"../yum-repo-test-dir");
    79     comps=plover_transaction_helper_get_comps(helper,&err);
    80     g_assert(!err);
    81     g_assert(plover_comps_lookup_group(comps,"base"));
    82     prefix=plover_transaction_helper_get_prefix(helper,&err);
    83     g_assert(!err);
    84     g_assert_cmpstr(prefix,==,plover_default_prefix_for_vendor("Acme Corporation"));
    85     g_assert(!plover_transaction_helper_get_visible(helper));
    86     g_assert(!plover_transaction_helper_get_error(helper,NULL));
    87     g_object_unref(upstream);
    88     g_object_unref(installed);
    89     g_object_unref(helper);
    90 }
    91 
    92 static void test_install_group(void)
    93 {
    94     gchar *root;
    95     GError *err=NULL;
    96     PloverPackageSet *installed;
    97     PloverTransactionHelper *helper;
    98     root=g_strdup("razor-test-dir-XXXXXX");
    99     g_assert(mkdtemp(root));
   100     g_setenv("RAZOR_ROOT",root,TRUE);
   101     g_free(root);
   102     helper=get_transaction_helper();
   103     installed=plover_package_set_new_from_installed("../razor-test-dir",&err);
   104     if (!installed)
   105 	g_error("../razor-test-dir: %s",err->message);
   106     plover_transaction_helper_set_installed(helper,installed);
   107     g_object_unref(installed);
   108     plover_transaction_helper_set_base(helper,"../yum-repo-test-dir");
   109     if (!plover_transaction_helper_install_group(helper,"base",&err))
   110 	g_error("base: %s",err->message);
   111     g_assert(!err);
   112     g_object_unref(helper);
   113     g_unsetenv("RAZOR_ROOT");
   114 }
   115 
   116 static void test_remove_group(void)
   117 {
   118     gchar *root;
   119     GError *err=NULL;
   120     PloverPackageSet *installed;
   121     PloverTransactionHelper *helper;
   122     struct plover_vector *packages;
   123     char *pkgs[]={"zip",NULL};
   124     root=g_strdup("razor-test-dir-XXXXXX");
   125     g_assert(mkdtemp(root));
   126     g_setenv("RAZOR_ROOT",root,TRUE);
   127     helper=get_transaction_helper();
   128     plover_transaction_helper_set_base(helper,"../yum-repo-test-dir");
   129     packages=plover_transaction_helper_group_get_default_packages(helper,
   130       "zappy",&err);
   131     if (!packages)
   132 	g_error("zappy: %s",err->message);
   133     if (!plover_install("../yum-repo-test-dir",NULL,packages->strings,&err))
   134 	g_error("plover_install: %s",err->message);
   135     plover_vector_free(packages);
   136     installed=plover_package_set_new_from_installed(root,&err);
   137     if (!installed)
   138 	g_error("%s: %s",root,err->message);
   139     plover_transaction_helper_set_installed(helper,installed);
   140     g_object_unref(installed);
   141     if (!plover_transaction_helper_remove_group(helper,"zappy",&err))
   142 	g_error("zappy: %s",err->message);
   143     g_assert(!err);
   144     g_object_unref(helper);
   145     g_unsetenv("RAZOR_ROOT");
   146     g_free(root);
   147 }
   148 
   149 static void test_update(void)
   150 {
   151     gchar *root;
   152     GError *err=NULL;
   153     PloverPackageSet *installed;
   154     PloverTransactionHelper *helper;
   155     root=g_strdup("razor-test-dir-XXXXXX");
   156     g_assert(mkdtemp(root));
   157     g_setenv("RAZOR_ROOT",root,TRUE);
   158     g_free(root);
   159     helper=get_transaction_helper();
   160     installed=plover_package_set_new_from_installed("../razor-test-dir",&err);
   161     if (!installed)
   162 	g_error("../razor-test-dir: %s",err->message);
   163     plover_transaction_helper_set_installed(helper,installed);
   164     g_object_unref(installed);
   165     plover_transaction_helper_set_base(helper,"../yum-repo-test-dir");
   166     if (plover_transaction_helper_update(helper,&err))
   167 	g_error("plover_transaction_helper_update reports work to be done");
   168     g_assert_error(err,PLOVER_GENERAL_ERROR,PLOVER_GENERAL_ERROR_NO_WORK);
   169     g_object_unref(helper);
   170     g_unsetenv("RAZOR_ROOT");
   171 }
   172 
   173 struct run_install_baton {
   174     enum {
   175 	RI_STATE_INIT = 0,
   176 	RI_STATE_SUMMARY,
   177 	RI_STATE_PROGRESS,
   178 	RI_STATE_PROGRESS_DELAY,
   179 	RI_STATE_DONE,
   180 	RI_STATE_FINISH
   181     } state;
   182     guint eid;		/* event ID (or 0) */
   183     PloverTransactionHelper *helper;
   184 };
   185 
   186 gboolean run_install_tick(gpointer data)
   187 {
   188     gboolean retval=TRUE;
   189     struct run_install_baton *baton=data;
   190     GtkWidget *page;
   191     GtkAssistant *assistant=baton->helper->assistant;
   192     switch(baton->state)
   193     {
   194 	case RI_STATE_INIT:
   195 	    if (!assistant || !gtk_widget_get_visible(GTK_WIDGET(assistant)))
   196 		return TRUE;
   197 	    if (!manual_mode)
   198 		gtk_button_clicked(GTK_BUTTON(assistant->forward));
   199 	    break;
   200 	case RI_STATE_SUMMARY:
   201 	    if (gtk_assistant_get_current_page(assistant)<1)
   202 		return TRUE;
   203 	    if (!manual_mode)
   204 		gtk_button_clicked(GTK_BUTTON(assistant->apply));
   205 	    break;
   206 	case RI_STATE_PROGRESS:
   207 	    if (gtk_assistant_get_current_page(assistant)<2)
   208 		return TRUE;
   209 	    page=gtk_assistant_get_nth_page(assistant,2);
   210 	    baton->eid=g_timeout_add_seconds(1,run_install_tick,baton);
   211 	    if (!gtk_assistant_get_page_complete(assistant,page))
   212 		return FALSE;
   213 	    else
   214 		retval=FALSE;
   215 	    break;
   216 	case RI_STATE_PROGRESS_DELAY:
   217 	    retval=FALSE;
   218 	    baton->eid=g_idle_add_full(G_PRIORITY_LOW,run_install_tick,baton,
   219 	      NULL);
   220 	    if (!manual_mode)
   221 		gtk_button_clicked(GTK_BUTTON(assistant->forward));
   222 	    break;
   223 	case RI_STATE_DONE:
   224 	    if (gtk_assistant_get_current_page(assistant)<3)
   225 		return TRUE;
   226 	    if (!manual_mode)
   227 		gtk_button_clicked(GTK_BUTTON(assistant->close));
   228 	    break;
   229 	case RI_STATE_FINISH:
   230 	    if (assistant && gtk_widget_get_visible(GTK_WIDGET(assistant)))
   231 		return TRUE;
   232 	    gtk_main_quit();
   233 	    baton->eid=0;
   234 	    return FALSE;
   235     }
   236     baton->state++;
   237     return retval;
   238 }
   239 
   240 static void test_run_install(void)
   241 {
   242     gchar *root;
   243     GError *err=NULL;
   244     struct plover_vector *packages;
   245     PloverPackageSet *installed;
   246     PloverTransactionHelper *helper;
   247     struct run_install_baton baton={0,};
   248     root=g_strdup("razor-test-dir-XXXXXX");
   249     g_assert(mkdtemp(root));
   250     g_setenv("RAZOR_ROOT",root,TRUE);
   251     helper=get_transaction_helper();
   252     installed=plover_package_set_new();
   253     if (!plover_package_set_open(installed,root,TRUE,&err))
   254 	g_error("%s: %s",root,err->message);
   255     plover_transaction_helper_set_installed(helper,installed);
   256     g_object_unref(installed);
   257     plover_transaction_helper_set_base(helper,"../yum-repo-test-dir");
   258     packages=plover_vector_new();
   259     plover_vector_append(packages,"zappy-tools");
   260     if (!plover_transaction_helper_install_packages(helper,packages,&err))
   261 	g_error("zappy-tools: %s",err->message);
   262     g_assert(!err);
   263     plover_vector_free(packages);
   264     plover_transaction_helper_present(helper);
   265     baton.helper=helper;
   266     baton.eid=g_idle_add_full(G_PRIORITY_LOW,run_install_tick,&baton,NULL);
   267     gtk_main();
   268     g_object_unref(helper);
   269     g_unsetenv("RAZOR_ROOT");
   270     g_free(root);
   271 }
   272 
   273 struct run_remove_baton {
   274     enum {
   275 	RR_STATE_INIT = 0,
   276 	RR_STATE_SUMMARY,
   277 	RR_STATE_PROGRESS,
   278 	RR_STATE_PROGRESS_DELAY,
   279 	RR_STATE_DONE,
   280 	RR_STATE_FINISH
   281     } state;
   282     guint eid;		/* event ID (or 0) */
   283     PloverTransactionHelper *helper;
   284 };
   285 
   286 gboolean run_remove_tick(gpointer data)
   287 {
   288     gboolean retval=TRUE;
   289     struct run_remove_baton *baton=data;
   290     GtkWidget *page;
   291     GtkAssistant *assistant=baton->helper->assistant;
   292     switch(baton->state)
   293     {
   294 	case RR_STATE_INIT:
   295 	    if (!assistant || !gtk_widget_get_visible(GTK_WIDGET(assistant)))
   296 		return TRUE;
   297 	    if (!manual_mode)
   298 		gtk_button_clicked(GTK_BUTTON(assistant->forward));
   299 	    break;
   300 	case RR_STATE_SUMMARY:
   301 	    if (gtk_assistant_get_current_page(assistant)<1)
   302 		return TRUE;
   303 	    if (!manual_mode)
   304 		gtk_button_clicked(GTK_BUTTON(assistant->apply));
   305 	    break;
   306 	case RR_STATE_PROGRESS:
   307 	    if (gtk_assistant_get_current_page(assistant)<2)
   308 		return TRUE;
   309 	    page=gtk_assistant_get_nth_page(assistant,2);
   310 	    baton->eid=g_timeout_add_seconds(1,run_remove_tick,baton);
   311 	    if (!gtk_assistant_get_page_complete(assistant,page))
   312 		return FALSE;
   313 	    else
   314 		retval=FALSE;
   315 	    break;
   316 	case RR_STATE_PROGRESS_DELAY:
   317 	    retval=FALSE;
   318 	    baton->eid=g_idle_add_full(G_PRIORITY_LOW,run_remove_tick,baton,
   319 	      NULL);
   320 	    if (!manual_mode)
   321 		gtk_button_clicked(GTK_BUTTON(assistant->forward));
   322 	    break;
   323 	case RR_STATE_DONE:
   324 	    if (gtk_assistant_get_current_page(assistant)<3)
   325 		return TRUE;
   326 	    if (!manual_mode)
   327 		gtk_button_clicked(GTK_BUTTON(assistant->close));
   328 	    break;
   329 	case RR_STATE_FINISH:
   330 	    if (assistant && gtk_widget_get_visible(GTK_WIDGET(assistant)))
   331 		return TRUE;
   332 	    gtk_main_quit();
   333 	    baton->eid=0;
   334 	    return FALSE;
   335     }
   336     baton->state++;
   337     return retval;
   338 }
   339 
   340 static void test_run_remove(void)
   341 {
   342     gchar *root;
   343     GError *err=NULL;
   344     struct plover_vector *packages;
   345     PloverPackageSet *installed;
   346     PloverTransactionHelper *helper;
   347     struct run_remove_baton baton={0,};
   348     root=g_strdup("razor-test-dir-XXXXXX");
   349     g_assert(mkdtemp(root));
   350     g_setenv("RAZOR_ROOT",root,TRUE);
   351     helper=get_transaction_helper();
   352     plover_transaction_helper_set_base(helper,"../yum-repo-test-dir");
   353     packages=
   354       plover_transaction_helper_group_get_default_packages(helper,"zappy",&err);
   355     if (!packages)
   356 	g_error("zappy: %s",err->message);
   357     if (!plover_install("../yum-repo-test-dir",NULL,packages->strings,&err))
   358 	g_error("plover_install: %s",err->message);
   359     plover_vector_free(packages);
   360     installed=plover_package_set_new();
   361     if (!plover_package_set_open(installed,root,TRUE,&err))
   362 	g_error("%s: %s",root,err->message);
   363     plover_transaction_helper_set_installed(helper,installed);
   364     g_object_unref(installed);
   365     if (!plover_transaction_helper_remove_group(helper,"zappy",&err))
   366 	g_error("zappy: %s",err->message);
   367     g_assert(!err);
   368     plover_transaction_helper_present(helper);
   369     baton.helper=helper;
   370     baton.eid=g_idle_add_full(G_PRIORITY_LOW,run_remove_tick,&baton,NULL);
   371     gtk_main();
   372     g_object_unref(helper);
   373     g_unsetenv("RAZOR_ROOT");
   374     g_free(root);
   375 }
   376 
   377 struct run_update_baton {
   378     enum {
   379 	RU_STATE_INIT = 0,
   380 	RU_STATE_SUMMARY,
   381 	RU_STATE_PROGRESS,
   382 	RU_STATE_PROGRESS_DELAY,
   383 	RU_STATE_DONE,
   384 	RU_STATE_FINISH
   385     } state;
   386     guint eid;		/* event ID (or 0) */
   387     PloverTransactionHelper *helper;
   388 };
   389 
   390 gboolean run_update_tick(gpointer data)
   391 {
   392     gboolean retval=TRUE;
   393     struct run_update_baton *baton=data;
   394     GtkWidget *page;
   395     GtkAssistant *assistant=baton->helper->assistant;
   396     switch(baton->state)
   397     {
   398 	case RU_STATE_INIT:
   399 	    if (!assistant || !gtk_widget_get_visible(GTK_WIDGET(assistant)))
   400 		return TRUE;
   401 	    if (!manual_mode)
   402 		gtk_button_clicked(GTK_BUTTON(assistant->forward));
   403 	    break;
   404 	case RU_STATE_SUMMARY:
   405 	    if (gtk_assistant_get_current_page(assistant)<1)
   406 		return TRUE;
   407 	    if (!manual_mode)
   408 		gtk_button_clicked(GTK_BUTTON(assistant->apply));
   409 	    break;
   410 	case RU_STATE_PROGRESS:
   411 	    if (gtk_assistant_get_current_page(assistant)<2)
   412 		return TRUE;
   413 	    page=gtk_assistant_get_nth_page(assistant,2);
   414 	    baton->eid=g_timeout_add_seconds(1,run_update_tick,baton);
   415 	    if (!gtk_assistant_get_page_complete(assistant,page))
   416 		return FALSE;
   417 	    else
   418 		retval=FALSE;
   419 	    break;
   420 	case RU_STATE_PROGRESS_DELAY:
   421 	    retval=FALSE;
   422 	    baton->eid=g_idle_add_full(G_PRIORITY_LOW,run_update_tick,baton,
   423 	      NULL);
   424 	    if (!manual_mode)
   425 		gtk_button_clicked(GTK_BUTTON(assistant->forward));
   426 	    break;
   427 	case RU_STATE_DONE:
   428 	    if (gtk_assistant_get_current_page(assistant)<3)
   429 		return TRUE;
   430 	    if (!manual_mode)
   431 		gtk_button_clicked(GTK_BUTTON(assistant->close));
   432 	    break;
   433 	case RU_STATE_FINISH:
   434 	    if (assistant && gtk_widget_get_visible(GTK_WIDGET(assistant)))
   435 		return TRUE;
   436 	    gtk_main_quit();
   437 	    baton->eid=0;
   438 	    return FALSE;
   439     }
   440     baton->state++;
   441     return retval;
   442 }
   443 
   444 static void test_run_update(void)
   445 {
   446     gchar *root;
   447     GError *err=NULL;
   448     struct razor_importer *importer;
   449     struct razor_set *downgraded;
   450     struct razor_atomic *atomic;
   451     struct plover_vector *packages;
   452     PloverPackageSet *installed;
   453     PloverTransactionHelper *helper;
   454     struct run_update_baton baton={0,};
   455     root=g_strdup("razor-test-dir-XXXXXX");
   456     g_assert(mkdtemp(root));
   457     g_setenv("RAZOR_ROOT",root,TRUE);
   458     helper=get_transaction_helper();
   459     plover_transaction_helper_set_base(helper,"../yum-repo-test-dir");
   460     installed=plover_package_set_new();
   461     if (!plover_package_set_open(installed,root,TRUE,&err))
   462 	g_error("%s: %s",root,err->message);
   463     importer=razor_importer_create();
   464     razor_importer_begin_package(importer,"zappy","0-1","noarch");
   465     razor_importer_add_details(importer,"","","","");
   466     razor_importer_add_property(importer,"zappy",RAZOR_PROPERTY_PROVIDES,"0-1");
   467     razor_importer_finish_package(importer);
   468     downgraded=razor_importer_finish(importer);
   469     atomic=razor_atomic_open("Add downgraded packages");
   470     if (!plover_package_set_update(installed,downgraded,atomic) ||
   471       razor_atomic_commit(atomic))
   472 	g_error("%s: %s",root,razor_atomic_get_error_msg(atomic));
   473     razor_atomic_destroy(atomic);
   474     razor_set_unref(downgraded);
   475     plover_transaction_helper_set_installed(helper,installed);
   476     g_object_unref(installed);
   477     if (!plover_transaction_helper_update(helper,&err))
   478 	g_error("update: %s",err->message);
   479     g_assert(!err);
   480     plover_transaction_helper_present(helper);
   481     baton.helper=helper;
   482     baton.eid=g_idle_add_full(G_PRIORITY_LOW,run_update_tick,&baton,NULL);
   483     gtk_main();
   484     g_object_unref(helper);
   485     g_unsetenv("RAZOR_ROOT");
   486     g_free(root);
   487 }
   488 
   489 struct check_vendor_baton {
   490     enum {
   491 	CV_STATE_INIT = 0,
   492 	CV_STATE_SUMMARY,
   493 	CV_STATE_PROGRESS,
   494 	CV_STATE_PROGRESS_DELAY,
   495 	CV_STATE_DONE,
   496 	CV_STATE_FINISH
   497     } state;
   498     guint eid;		/* event ID (or 0) */
   499     PloverTransactionHelper *helper;
   500 };
   501 
   502 gboolean check_vendor_tick(gpointer data)
   503 {
   504     gboolean retval=TRUE;
   505     struct check_vendor_baton *baton=data;
   506     GtkWidget *page,*w;
   507     GtkAssistant *assistant=baton->helper->assistant;
   508     switch(baton->state)
   509     {
   510 	case CV_STATE_INIT:
   511 	    if (!assistant || !gtk_widget_get_visible(GTK_WIDGET(assistant)))
   512 		return TRUE;
   513 	    if (!manual_mode)
   514 		gtk_button_clicked(GTK_BUTTON(assistant->forward));
   515 	    break;
   516 	case CV_STATE_SUMMARY:
   517 	    if (gtk_assistant_get_current_page(assistant)<1)
   518 		return TRUE;
   519 	    g_assert(!gtk_widget_is_sensitive(assistant->apply));
   520 	    w=GTK_WIDGET(gtk_builder_get_object(ui,"SIRemoveExisting"));
   521 	    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w),TRUE);
   522 	    g_assert(gtk_widget_is_sensitive(assistant->apply));
   523 	    if (!manual_mode)
   524 		gtk_button_clicked(GTK_BUTTON(assistant->apply));
   525 	    break;
   526 	case CV_STATE_PROGRESS:
   527 	    if (gtk_assistant_get_current_page(assistant)<2)
   528 		return TRUE;
   529 	    page=gtk_assistant_get_nth_page(assistant,2);
   530 	    baton->eid=g_timeout_add_seconds(1,check_vendor_tick,baton);
   531 	    if (!gtk_assistant_get_page_complete(assistant,page))
   532 		return FALSE;
   533 	    else
   534 		retval=FALSE;
   535 	    break;
   536 	case CV_STATE_PROGRESS_DELAY:
   537 	    retval=FALSE;
   538 	    baton->eid=g_idle_add_full(G_PRIORITY_LOW,check_vendor_tick,baton,
   539 	      NULL);
   540 	    if (!manual_mode)
   541 		gtk_button_clicked(GTK_BUTTON(assistant->forward));
   542 	    break;
   543 	case CV_STATE_DONE:
   544 	    if (gtk_assistant_get_current_page(assistant)<3)
   545 		return TRUE;
   546 	    if (!manual_mode)
   547 		gtk_button_clicked(GTK_BUTTON(assistant->close));
   548 	    break;
   549 	case CV_STATE_FINISH:
   550 	    if (assistant && gtk_widget_get_visible(GTK_WIDGET(assistant)))
   551 		return TRUE;
   552 	    gtk_main_quit();
   553 	    baton->eid=0;
   554 	    return FALSE;
   555     }
   556     baton->state++;
   557     return retval;
   558 }
   559 
   560 static void test_check_vendor(void)
   561 {
   562     int fh;
   563     gchar *root,*s;
   564     GError *err=NULL;
   565     struct razor_importer *importer;
   566     struct razor_set *downgraded;
   567     struct razor_atomic *atomic;
   568     struct plover_vector *packages;
   569     PloverPackageSet *installed;
   570     PloverTransactionHelper *helper;
   571     struct run_update_baton baton={0,};
   572     g_setenv("PLOVER_VENDOR_PREFIX","/srv",TRUE);
   573     root=g_strdup("razor-test-dir-XXXXXX");
   574     g_assert(mkdtemp(root));
   575     g_setenv("RAZOR_ROOT",root,TRUE);
   576     helper=get_transaction_helper();
   577     plover_transaction_helper_set_check_vendor(helper,TRUE);
   578     plover_transaction_helper_set_base(helper,"../yum-repo-test-dir");
   579     installed=plover_package_set_new();
   580     if (!plover_package_set_open(installed,root,TRUE,&err))
   581 	g_error("%s: %s",root,err->message);
   582     importer=razor_importer_create();
   583     razor_importer_begin_package(importer,"zappy","0-1","noarch");
   584     razor_importer_add_details(importer,"","","","");
   585     razor_importer_add_property(importer,"zappy",RAZOR_PROPERTY_PROVIDES,"0-1");
   586     razor_importer_add_install_prefix(importer,"/test");
   587     razor_importer_add_file(importer,"/test/bin/zappy");
   588     razor_importer_finish_package(importer);
   589     downgraded=razor_importer_finish(importer);
   590     atomic=razor_atomic_open("Add downgraded packages");
   591     razor_atomic_make_dirs(atomic,root,"/test/bin/zappy");
   592     s=g_build_filename(root,"test/bin/zappy",NULL);
   593     fh=razor_atomic_create_file(atomic,s,S_IRWXU|S_IRWXG|S_IRWXO);
   594     g_free(s);
   595     razor_atomic_close(atomic,fh);
   596     if (!plover_package_set_update(installed,downgraded,atomic) ||
   597       razor_atomic_commit(atomic))
   598 	g_error("%s: %s",root,razor_atomic_get_error_msg(atomic));
   599     razor_atomic_destroy(atomic);
   600     razor_set_unref(downgraded);
   601     plover_transaction_helper_set_installed(helper,installed);
   602     g_object_unref(installed);
   603     if (!plover_transaction_helper_update(helper,&err))
   604 	g_error("update: %s",err->message);
   605     g_assert(!err);
   606     plover_transaction_helper_present(helper);
   607     baton.helper=helper;
   608     baton.eid=g_idle_add_full(G_PRIORITY_LOW,check_vendor_tick,&baton,NULL);
   609     gtk_main();
   610     g_object_unref(helper);
   611     g_unsetenv("RAZOR_ROOT");
   612     g_free(root);
   613     g_unsetenv("PLOVER_VENDOR_PREFIX");
   614 }
   615 
   616 struct set_error_baton {
   617     enum {
   618 	SE_STATE_INIT = 0,
   619 	SE_STATE_FINISH
   620     } state;
   621     PloverTransactionHelper *helper;
   622 };
   623 
   624 /*
   625  * This handler may be called as either an event (ie., idle or timeout)
   626  * or as a (swapped) signal. In the latter case, the return is ignored.
   627  */
   628 gboolean set_error_tick(gpointer data)
   629 {
   630     struct set_error_baton *baton=data;
   631     GtkDialog *dlg;
   632     GtkWidget *button;
   633     dlg=GTK_DIALOG(baton->helper->error_dialog);
   634     switch(baton->state)
   635     {
   636 	case SE_STATE_INIT:
   637 	    if (!dlg || !gtk_widget_get_visible(GTK_WIDGET(dlg)))
   638 		return TRUE;
   639 	    button=gtk_dialog_get_widget_for_response(dlg,GTK_RESPONSE_CLOSE);
   640 	    if (!manual_mode)
   641 		gtk_button_clicked(GTK_BUTTON(button));
   642 	    break;
   643 	case SE_STATE_FINISH:
   644 	    if (dlg && gtk_widget_get_visible(GTK_WIDGET(dlg)))
   645 		return TRUE;
   646 	    gtk_main_quit();
   647 	    return FALSE;
   648     }
   649     baton->state++;
   650     return TRUE;
   651 }
   652 
   653 static void test_set_error(void)
   654 {
   655     gchar *root;
   656     const char *errmsg;
   657     GError *err=NULL;
   658     const GError *err2=NULL;
   659     PloverPackageSet *installed;
   660     PloverTransactionHelper *helper;
   661     struct set_error_baton baton={0,};
   662     root=g_strdup("razor-test-dir-XXXXXX");
   663     g_assert(mkdtemp(root));
   664     g_setenv("RAZOR_ROOT",root,TRUE);
   665     g_free(root);
   666     helper=get_transaction_helper();
   667     installed=plover_package_set_new_from_installed("../razor-test-dir",&err);
   668     if (!installed)
   669 	g_error("../razor-test-dir: %s",err->message);
   670     plover_transaction_helper_set_installed(helper,installed);
   671     g_object_unref(installed);
   672     plover_transaction_helper_set_base(helper,"../yum-repo-test-dir");
   673     if (!plover_transaction_helper_update(helper,&err))
   674 	plover_transaction_helper_set_error(helper,err,"Expected error");
   675     g_assert(plover_transaction_helper_get_visible(helper));
   676     errmsg=plover_transaction_helper_get_error(helper,&err2);
   677     g_assert_cmpstr(errmsg,==,"Expected error");
   678     g_assert_error(err2,err->domain,err->code);
   679     plover_transaction_helper_present(helper);
   680     baton.helper=helper;
   681     g_idle_add_full(G_PRIORITY_LOW,set_error_tick,&baton,NULL);
   682     g_error_free(err);
   683     gtk_main();
   684     g_object_unref(helper);
   685     g_unsetenv("RAZOR_ROOT");
   686 }
   687 
   688 int main(int argc,char **argv)
   689 {
   690     int retval;
   691     GError *err=NULL;
   692     /*
   693      * Note that because g_test_init() handles --help,
   694      * these options will not appear in the output.
   695      */
   696     GOptionEntry options[]={
   697 	{"manual",0,0,G_OPTION_ARG_NONE,&manual_mode,
   698 	  "Disable automatic mode",NULL},
   699 	{NULL}
   700     };
   701     g_test_init(&argc,&argv,NULL);
   702     g_setenv("GTK_MODULES","",TRUE);
   703     g_setenv("GTK2_RC_FILES","/dev/null",TRUE);
   704     gtk_disable_setlocale();
   705     setlocale(LC_ALL,"C");
   706     g_test_bug_base("mailto:ali@juiblex.co.uk");
   707     if (!gtk_init_with_args(&argc,&argv,NULL,options,NULL,&err))
   708     {
   709 	g_printf("%s\n",err->message);
   710 	exit(0);
   711     }
   712     g_test_add_func("/transactionhelper/init",test_init);
   713     g_test_add_func("/transactionhelper/basic-properties",
   714       test_basic_properties);
   715     g_test_add_func("/transactionhelper/install-group",test_install_group);
   716     g_test_add_func("/transactionhelper/remove-group",test_remove_group);
   717     g_test_add_func("/transactionhelper/update",test_update);
   718     g_test_add_func("/transactionhelper/run-install",test_run_install);
   719     g_test_add_func("/transactionhelper/run-remove",test_run_remove);
   720     g_test_add_func("/transactionhelper/run-update",test_run_update);
   721     g_test_add_func("/transactionhelper/check-vendor",test_check_vendor);
   722     g_test_add_func("/transactionhelper/set-error",test_set_error);
   723     retval=g_test_run();
   724     return retval;
   725 }