Hi, The attached patch adds (optional) support for the subunit protocol to mapitest.
This is intended for use in an "overarching" test system, where we can run a range of tests (e.g. mapitest, command line tools like openchangeclient, smbtorture tests, and also do server setup / teardown), and check the results. I'm planning to use subunit for some of it, to summarise the tests. Unfortunately subunit isn't packaged on fedora, so it would require building from source (which is pretty easy) until that is sorted out. The dependency is completely optional though. Thoughts? Comments? Brad
Index: config.mk.in =================================================================== --- config.mk.in (revision 1732) +++ config.mk.in (working copy) @@ -29,7 +29,7 @@ sambapref...@sambaprefix@ DSOOPT=-shared -fPIC -cfla...@cflags@ @COMPILER_OPTIONS_C@ @ASSERT_DEFINITION@ \ +cfla...@cflags@ @COMPILER_OPTIONS_C@ @ASSERT_DEFINITION@ @SUBUNIT_CFLAGS@ \ -DDEFAULT_LDIF=\"$(datadir)/setup/profiles\" \ -DMAPISTORE_BACKEND_INSTALLDIR=\"$(libdir)/mapistore_backends\" \ -DMAPISTORE_MAPPING_PATH=\"$(prefix)/private/mapistore\" @@ -101,6 +101,8 @@ mapistore_te...@mapistore_test@ +subunit_li...@subunit_libs@ + # SWIG swigdirs-a...@swigdirsall@ swigdirs-insta...@swigdirsinstall@ Index: configure.ac =================================================================== --- configure.ac (revision 1732) +++ configure.ac (working copy) @@ -609,6 +609,20 @@ fi dnl ########################################################################## +dnl (Optional) subunit support in mapitest +dnl ########################################################################## +PKG_CHECK_MODULES(SUBUNIT, libsubunit, found_subunit=yes, found_subunit=no) +AC_SUBST(SUBUNIT_CFLAGS) +AC_SUBST(SUBUNIT_LIBS) + +if test x"$found_subunit" = x"yes"; then + AC_DEFINE(HAVE_SUBUNIT, 1, [Define if you want to use subunit]) + have_subunit="yes" +else + have_subunit="no" +fi + +dnl ########################################################################## dnl Qt4 support dnl ########################################################################## AC_ARG_ENABLE(openchange-qt4, @@ -703,6 +717,8 @@ * OpenChange Torture Suite: $enable_torture + * subunit format (mapitest): $have_subunit + * OpenChange Documentation: $enable_doxygen * Coverage Tests: $use_cov Index: Makefile =================================================================== --- Makefile (revision 1732) +++ Makefile (working copy) @@ -1379,7 +1379,7 @@ utils/mapitest/modules/module_mapidump.o \ libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) @echo "Linking $@" - @$(CC) -o $@ $^ $(LDFLAGS) $(LIBS) -lpopt + @$(CC) -o $@ $^ $(LDFLAGS) $(LIBS) -lpopt $(SUBUNIT_LIBS) utils/mapitest/proto.h: \ utils/mapitest/mapitest_suite.c \ Index: utils/mapitest/mapitest_print.c =================================================================== --- utils/mapitest/mapitest_print.c (revision 1732) +++ utils/mapitest/mapitest_print.c (working copy) @@ -23,6 +23,11 @@ #include <samba/version.h> #include <utils/mapitest/mapitest.h> +#include "config.h" +#ifdef HAVE_SUBUNIT +#include <subunit/child.h> +#endif + #include <time.h> static int count = 0; @@ -78,6 +83,10 @@ char *s = NULL; int ret; + if (mt->subunit_output) { + return; + } + va_start(ap, format); ret = vasprintf(&s, format, ap); va_end(ap); @@ -97,6 +106,10 @@ { int i; + if (mt->subunit_output) { + return; + } + for (i = 0; i < count; i++) { fprintf(mt->stream, "\n"); } @@ -113,6 +126,10 @@ { int i; + if (mt->subunit_output) { + return; + } + for (i = 0; i < len; i++) { fprintf(mt->stream, "%c", delim); } @@ -151,6 +168,11 @@ */ _PUBLIC_ void mapitest_print_title(struct mapitest *mt, const char *str, char delim) { + /* we handle this outside mapitest if we're using subunit */ + if (mt->subunit_output) { + return; + } + mapitest_underline(mt, str, delim); mapitest_indent(); } @@ -192,7 +214,7 @@ /** - \details print the test tile + \details print the test title \param mt pointer to the top-level mapitest structure \param str the test title @@ -203,6 +225,12 @@ if (!str) return; +#ifdef HAVE_SUBUNIT + if (mt->subunit_output) { + subunit_test_start(str); + return; + } +#endif title = talloc_asprintf(mt->mem_ctx, MODULE_TEST_TITLE, str); mapitest_print(mt, "%s", title); mapitest_print_tab(mt); @@ -342,6 +370,10 @@ */ _PUBLIC_ void mapitest_print_headers(struct mapitest *mt) { + if (mt->subunit_output) { + return; + } + mapitest_print_headers_start(mt); mapitest_indent(); mapitest_print_headers_info(mt); @@ -363,11 +395,22 @@ */ _PUBLIC_ void mapitest_print_test_result(struct mapitest *mt, char *name, bool ret) { +#ifdef HAVE_SUBUNIT + if (mt->subunit_output) { + if (ret == true) { + subunit_test_pass(name); + } else { + subunit_test_fail(name, "failed"); + } + } else +#endif + { mapitest_print(mt, MODULE_TEST_RESULT, name, (ret == true) ? MODULE_TEST_SUCCESS : MODULE_TEST_FAILURE); mapitest_print_tab(mt); mapitest_print_line(mt, MODULE_TEST_LINELEN, MODULE_TEST_DELIM2); mapitest_print_newline(mt, MODULE_TEST_NEWLINE); + } } @@ -383,6 +426,10 @@ { const char *retstr = NULL; + if (mt->subunit_output) { + return; + } + retstr = mapi_get_errstr(GetLastError()); if (mt->color == true) { @@ -507,3 +554,62 @@ } free(s); } + +/** + Output a set of rows from a table + + \param mt pointer to the top-level mapitest structure + \param rowset the rows to output + \param sep a separator / spacer to insert in front of the label + + \note this is a simple wrapper for mapidump_SRowSet(), only for use in mapitest. +*/ +_PUBLIC_ void mapitest_print_SRowSet(struct mapitest *mt, struct SRowSet *rowset, const char *sep) +{ + if (mt->subunit_output) { + return; + } + + mapidump_SRowSet(rowset, sep); +} + +/** + Output a row of the public address book + + \param mt pointer to the top-level mapitest structure + \param lpProp the property to print + \param sep a separator / spacer to insert in front of the label + + \note this is a simple wrapper for mapidump_SPropValue(), only for use in mapitest. +*/ +_PUBLIC_ void mapitest_print_SPropValue(struct mapitest *mt, struct SPropValue lpProp, const char *sep) +{ + if (mt->subunit_output) { + return; + } + + mapidump_SPropValue(lpProp, sep); +} + +/** + Output a row of the public address book + + \param mt pointer to the top-level mapitest structure + \param aRow one row of the public address book (Global Address List) + + This function is usually used with GetGALTable, which can obtain several + rows at once - you'll need to iterate over the rows. + + The SRow is assumed to contain entries for PR_ADDRTYPE_UNICODE, PR_DISPLAY_NAME_UNICODE, + PR_EMAIL_ADDRESS_UNICODE and PR_ACCOUNT_UNICODE. + + \note this is a simple wrapper for mapidump_PAB_entry(), only for use in mapitest. +*/ +_PUBLIC_ void mapitest_print_PAB_entry(struct mapitest *mt, struct SRow *aRow) +{ + if (mt->subunit_output) { + return; + } + + mapidump_PAB_entry(aRow); +} Index: utils/mapitest/mapitest.c =================================================================== --- utils/mapitest/mapitest.c (revision 1732) +++ utils/mapitest/mapitest.c (working copy) @@ -23,6 +23,8 @@ #include <samba/popt.h> #include <param.h> +#include "config.h" + #include <utils/openchange-tools.h> #include "utils/mapitest/mapitest.h" @@ -50,6 +52,7 @@ mt->mapi_suite = false; mt->cmdline_calls = NULL; mt->cmdline_suite = NULL; + mt->subunit_output = false; } /** @@ -211,7 +214,7 @@ enum { OPT_PROFILE_DB=1000, OPT_PROFILE, OPT_PASSWORD, OPT_CONFIDENTIAL, OPT_OUTFILE, OPT_MAPI_CALLS, OPT_NO_SERVER, OPT_LIST_ALL, OPT_DUMP_DATA, - OPT_DEBUG, OPT_COLOR }; + OPT_DEBUG, OPT_COLOR, OPT_SUBUNIT }; struct poptOption long_options[] = { POPT_AUTOHELP @@ -220,6 +223,9 @@ { "password", 'p', POPT_ARG_STRING, NULL, OPT_PASSWORD, "set the profile or account password", NULL }, { "confidential", 0, POPT_ARG_NONE, NULL, OPT_CONFIDENTIAL, "remove any sensitive data from the report", NULL }, { "color", 0, POPT_ARG_NONE, NULL, OPT_COLOR, "color MAPI retval", NULL }, +#if HAVE_SUBUNIT + { "subunit", 0, POPT_ARG_NONE, NULL, OPT_SUBUNIT, "output in subunit protocol format", NULL }, +#endif { "outfile", 'o', POPT_ARG_STRING, NULL, OPT_OUTFILE, "set the report output file", NULL }, { "mapi-calls", 0, POPT_ARG_STRING, NULL, OPT_MAPI_CALLS, "test custom ExchangeRPC tests", NULL }, { "list-all", 0, POPT_ARG_NONE, NULL, OPT_LIST_ALL, "list suite and tests - names and description", NULL }, @@ -273,6 +279,9 @@ case OPT_COLOR: mt.color = true; break; + case OPT_SUBUNIT: + mt.subunit_output = true; + break; case OPT_LIST_ALL: mapitest_list(&mt, NULL); talloc_free(mem_ctx); Index: utils/mapitest/modules/module_oxcmsg.c =================================================================== --- utils/mapitest/modules/module_oxcmsg.c (revision 1732) +++ utils/mapitest/modules/module_oxcmsg.c (working copy) @@ -1299,7 +1299,7 @@ retval = GetRecipientTable(&obj_embeddedmsg, &SRowSet, &SPropTagArray); mapitest_print(mt, "* %-35s: 0x%.8x\n", "GetRecipientTable", retval); - mapidump_SRowSet(&SRowSet, "\t * "); + mapitest_print_SRowSet(mt, &SRowSet, "\t * "); mapi_object_release(&obj_embeddedmsg); /* Step 7. Delete the message */ Index: utils/mapitest/modules/module_oxcstor.c =================================================================== --- utils/mapitest/modules/module_oxcstor.c (revision 1732) +++ utils/mapitest/modules/module_oxcstor.c (working copy) @@ -381,7 +381,7 @@ return false; } - mapidump_SRowSet(&SRowSet, "\t\t[*]"); + mapitest_print_SRowSet(mt, &SRowSet, "\t\t[*]"); MAPIFreeBuffer(SRowSet.aRow); /* Release */ Index: utils/mapitest/modules/module_nspi.c =================================================================== --- utils/mapitest/modules/module_nspi.c (revision 1732) +++ utils/mapitest/modules/module_nspi.c (working copy) @@ -965,7 +965,7 @@ totalRowsFetched += rowsFetched; if (rowsFetched) { for (i = 0; i < rowsFetched; i++) { - mapidump_PAB_entry(&SRowSet->aRow[i]); + mapitest_print_PAB_entry(mt, &SRowSet->aRow[i]); } } ulFlags = TABLE_CUR; Index: utils/mapitest/modules/module_oxomsg.c =================================================================== --- utils/mapitest/modules/module_oxomsg.c (revision 1732) +++ utils/mapitest/modules/module_oxomsg.c (working copy) @@ -467,7 +467,7 @@ lpProp.dwAlignPad = 0; for (i = 0; i < lpProps.cValues; i++) { cast_SPropValue(&lpProps.lpProps[i], &lpProp); - mapidump_SPropValue(lpProp, "\t* "); + mapitest_print_SPropValue(mt, lpProp, "\t* "); } MAPIFreeBuffer(lpProps.lpProps); } Index: utils/mapitest/modules/module_oxcperm.c =================================================================== --- utils/mapitest/modules/module_oxcperm.c (revision 1732) +++ utils/mapitest/modules/module_oxcperm.c (working copy) @@ -34,7 +34,7 @@ This depends on PR_ENTRYID being the first property returned */ -static void mapitest_dump_SRowSet(struct SRowSet *SRowSet, const char *sep) +static void mapitest_dump_permissions_SRowSet(struct mapitest *mt, struct SRowSet *SRowSet, const char *sep) { uint32_t i, j; @@ -49,7 +49,7 @@ continue; } for (j = 0; j < thisRow->cValues; j++) { - mapidump_SPropValue(thisRow->lpProps[j], sep); + mapitest_print_SPropValue(mt, thisRow->lpProps[j], sep); } } } @@ -122,7 +122,7 @@ ret = false; goto cleanup; } - mapitest_dump_SRowSet(&SRowSet, "\t"); + mapitest_dump_permissions_SRowSet(mt, &SRowSet, "\t"); cleanup: mapi_object_release(&obj_permtable); @@ -218,7 +218,7 @@ ret = false; goto cleanup; } - mapitest_dump_SRowSet(&SRowSet, "\t"); + mapitest_dump_permissions_SRowSet(mt, &SRowSet, "\t"); /* Step 5. Modify user permissions on the folder, and check it */ retval = ModifyUserPermission(&obj_temp_folder, "Administrator", RightsAll); @@ -252,7 +252,7 @@ ret = false; goto cleanup; } - mapitest_dump_SRowSet(&SRowSet, "\t"); + mapitest_dump_permissions_SRowSet(mt, &SRowSet, "\t"); /* Step 6. Remove user permissions on the folder, and check it */ retval = RemoveUserPermission(&obj_temp_folder, "Administrator"); @@ -286,7 +286,7 @@ ret = false; goto cleanup; } - mapitest_dump_SRowSet(&SRowSet, "\t"); + mapitest_dump_permissions_SRowSet(mt, &SRowSet, "\t"); /* Step 7. Delete the folder */ retval = EmptyFolder(&obj_temp_folder); Index: utils/mapitest/mapitest.h =================================================================== --- utils/mapitest/mapitest.h (revision 1732) +++ utils/mapitest/mapitest.h (working copy) @@ -134,6 +134,7 @@ bool mapi_all; /*!< true if all tests should be run */ bool online; /*!< true if the server could be accessed */ bool color; /*!< true if the output should be colored */ + bool subunit_output; /*!< true if we should write output in subunit protocol format */ struct emsmdb_info info; struct mapitest_suite *mapi_suite; /*!< the various test suites */ struct mapitest_unit *cmdline_calls;
_______________________________________________ devel mailing list devel@lists.openchange.org http://mailman.openchange.org/listinfo/devel