2
Stand-alone MAPI testsuite
6
Copyright (C) Julien Kerihuel 2008
8
This program is free software; you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation; either version 3 of the License, or
11
(at your option) any later version.
13
This program is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
GNU General Public License for more details.
18
You should have received a copy of the GNU General Public License
19
along with this program. If not, see <http://www.gnu.org/licenses/>.
22
#include "utils/mapitest/mapitest.h"
23
#include "utils/openchange-tools.h"
25
#include <samba/popt.h>
32
Core of %mapitest implementation
36
Initialize %mapitest structure
38
static void mapitest_init(TALLOC_CTX *mem_ctx, struct mapitest *mt)
40
mt->mem_ctx = mem_ctx;
42
memset(&mt->info, 0, sizeof (mt->info));
47
mt->confidential = false;
48
mt->no_server = false;
51
mt->mapi_suite = false;
52
mt->cmdline_calls = NULL;
53
mt->cmdline_suite = NULL;
54
mt->subunit_output = false;
58
Initialize %mapitest output stream
60
\param mt pointer to mapitest context
61
\param filename filename to write to (can be null, for output to stdout)
63
static void mapitest_init_stream(struct mapitest *mt, const char *filename)
65
if (filename == NULL) {
66
mt->stream = fdopen(STDOUT_FILENO, "a");
68
mt->stream = fopen(filename, "w+");
71
if (mt->stream == NULL) {
72
err(errno, "fdopen/fopen");
77
Clean up %mapitest output stream
79
\param mt pointer to mapitest context
81
static void mapitest_cleanup_stream(struct mapitest *mt)
87
static bool mapitest_get_testnames(TALLOC_CTX *mem_ctx, struct mapitest *mt,
88
const char *parameter)
90
struct mapitest_unit *el = NULL;
93
if ((temptok = strtok((char *)parameter, ";")) == NULL) {
94
fprintf(stderr, "Invalid testname list [;]\n");
98
el = talloc_zero(mem_ctx, struct mapitest_unit);
99
el->name = talloc_strdup(mem_ctx, temptok);
100
DLIST_ADD(mt->cmdline_calls, el);
102
while ((temptok = strtok(NULL, ";")) != NULL) {
103
el = talloc_zero(mem_ctx, struct mapitest_unit);
104
el->name = talloc_strdup(mem_ctx, temptok);
105
DLIST_ADD_END(mt->cmdline_calls, el, struct mapitest_unit *);
112
static void mapitest_list(struct mapitest *mt, const char *name)
114
struct mapitest_suite *sel;
115
struct mapitest_test *el;
119
for (sel = mt->mapi_suite; sel; sel = sel->next) {
120
printf("[*] Suite %s\n", sel->name);
121
printf("===================================\n");
122
printf(" * %-15s %s\n", "Name:", sel->name);
123
printf(" * %-15s %5s\n", "Description:", sel->description);
124
printf(" * Running Tests:\n");
125
for (el = sel->tests; el; el = el->next) {
126
printf("\t - %-35s: %-10s\n", el->name, el->description);
135
* Retrieve server specific information
137
static bool mapitest_get_server_info(struct mapitest *mt,
139
const char *password,
141
const char *opt_debug)
144
enum MAPISTATUS retval;
145
struct emsmdb_info *info = NULL;
146
struct mapi_session *session = NULL;
148
/* if the user explicitly asked for just the no-server tests
149
to be run, then we're done here */
150
if (mt->no_server == true) return 0;
152
mem_ctx = talloc_named(NULL, 0, "mapitest_get_server_info");
154
/* if no profile was specified, get the default */
156
retval = GetDefaultProfile(mt->mapi_ctx, &opt_profname);
157
if (retval != MAPI_E_SUCCESS) {
158
mapi_errstr("GetDefaultProfile", retval);
159
talloc_free(mem_ctx);
166
SetMAPIDumpData(mt->mapi_ctx, opt_dumpdata);
169
SetMAPIDebugLevel(mt->mapi_ctx, atoi(opt_debug));
172
retval = MapiLogonEx(mt->mapi_ctx, &session, opt_profname, password);
173
MAPIFreeBuffer(opt_profname);
174
talloc_free(mem_ctx);
175
if (retval != MAPI_E_SUCCESS) {
176
mapi_errstr("MapiLogonEx", retval);
179
mt->session = session;
180
mt->profile = session->profile;
182
info = emsmdb_get_info(session);
183
memcpy(&mt->info, info, sizeof (struct emsmdb_info));
185
/* extract org and org_unit from info.mailbox */
186
mt->org = x500_get_dn_element(mt->mem_ctx, info->szDNPrefix, "/o=");
187
mt->org_unit = x500_get_dn_element(mt->mem_ctx, info->szDNPrefix, "/ou=");
197
int main(int argc, const char *argv[])
199
enum MAPISTATUS retval;
200
int32_t num_tests_failed;
206
bool opt_dumpdata = false;
207
const char *opt_debug = NULL;
208
const char *opt_profdb = NULL;
209
char *opt_profname = NULL;
210
const char *opt_password = NULL;
211
const char *opt_outfile = NULL;
212
char *prof_tmp = NULL;
213
bool opt_leak_report = false;
214
bool opt_leak_report_full = false;
216
enum { OPT_PROFILE_DB=1000, OPT_PROFILE, OPT_PASSWORD,
217
OPT_CONFIDENTIAL, OPT_OUTFILE, OPT_MAPI_CALLS,
218
OPT_NO_SERVER, OPT_LIST_ALL, OPT_DUMP_DATA,
219
OPT_DEBUG, OPT_COLOR, OPT_SUBUNIT, OPT_LEAK_REPORT,
220
OPT_LEAK_REPORT_FULL };
222
struct poptOption long_options[] = {
224
{ "database", 'f', POPT_ARG_STRING, NULL, OPT_PROFILE_DB, "set the profile database", NULL },
225
{ "profile", 'p', POPT_ARG_STRING, NULL, OPT_PROFILE, "set the profile name", NULL },
226
{ "password", 'p', POPT_ARG_STRING, NULL, OPT_PASSWORD, "set the profile or account password", NULL },
227
{ "confidential", 0, POPT_ARG_NONE, NULL, OPT_CONFIDENTIAL, "remove any sensitive data from the report", NULL },
228
{ "color", 0, POPT_ARG_NONE, NULL, OPT_COLOR, "color MAPI retval", NULL },
230
{ "subunit", 0, POPT_ARG_NONE, NULL, OPT_SUBUNIT, "output in subunit protocol format", NULL },
232
{ "outfile", 'o', POPT_ARG_STRING, NULL, OPT_OUTFILE, "set the report output file", NULL },
233
{ "mapi-calls", 0, POPT_ARG_STRING, NULL, OPT_MAPI_CALLS, "test custom ExchangeRPC tests", NULL },
234
{ "list-all", 0, POPT_ARG_NONE, NULL, OPT_LIST_ALL, "list suite and tests - names and description", NULL },
235
{ "no-server", 0, POPT_ARG_NONE, NULL, OPT_NO_SERVER, "only run tests that do not require server connection", NULL },
236
{ "dump-data", 0, POPT_ARG_NONE, NULL, OPT_DUMP_DATA, "dump the hex data", NULL },
237
{ "debuglevel", 'd', POPT_ARG_STRING, NULL, OPT_DEBUG, "set debug level", NULL },
238
{ "leak-report", 0, POPT_ARG_NONE, NULL, OPT_LEAK_REPORT, "enable talloc leak reporting on exit", NULL },
239
{ "leak-report-full", 0, POPT_ARG_NONE, NULL, OPT_LEAK_REPORT_FULL, "enable full talloc leak reporting on exit", NULL },
240
POPT_OPENCHANGE_VERSION
241
{ NULL, 0, 0, NULL, 0, NULL, NULL }
244
mem_ctx = talloc_named(NULL, 0, "mapitest");
245
mapitest_init(mem_ctx, &mt);
246
mapitest_register_modules(&mt);
248
pc = poptGetContext("mapitest", argc, argv, long_options, 0);
250
while ((opt = poptGetNextOpt(pc)) != -1) {
256
opt_debug = poptGetOptArg(pc);
259
opt_profdb = poptGetOptArg(pc);
262
prof_tmp = poptGetOptArg(pc);
263
opt_profname = talloc_strdup(mem_ctx, prof_tmp);
268
opt_password = poptGetOptArg(pc);
270
case OPT_CONFIDENTIAL:
271
mt.confidential = true;
274
opt_outfile = poptGetOptArg(pc);
277
ret = mapitest_get_testnames(mem_ctx, &mt, poptGetOptArg(pc));
278
if (ret == false) exit (-1);
288
mt.subunit_output = true;
291
mapitest_list(&mt, NULL);
292
talloc_free(mem_ctx);
296
case OPT_LEAK_REPORT:
297
opt_leak_report = true;
298
talloc_enable_leak_report();
300
case OPT_LEAK_REPORT_FULL:
301
opt_leak_report_full = true;
302
talloc_enable_leak_report_full();
310
if (mt.cmdline_calls && (mt.mapi_all == true)) {
311
fprintf(stderr, "mapi-calls and mapi-all can't be set at the same time\n");
315
/* Initialize MAPI subsystem */
317
opt_profdb = talloc_asprintf(mem_ctx, DEFAULT_PROFDB, getenv("HOME"));
320
retval = MAPIInitialize(&(mt.mapi_ctx), opt_profdb);
321
if (retval != MAPI_E_SUCCESS) {
322
mapi_errstr("MAPIInitialize", retval);
326
mapitest_init_stream(&mt, opt_outfile);
328
mt.online = mapitest_get_server_info(&mt, opt_profname, opt_password,
329
opt_dumpdata, opt_debug);
331
mapitest_print_headers(&mt);
333
/* Do not run any tests if we couldn't find a profile or if
334
* server is offline and connection to server was implicitly
336
if (!opt_profname && mt.online == false && mt.no_server == false) {
337
fprintf(stderr, "No MAPI profile found for online tests\n");
341
/* Run custom tests */
342
if (mt.cmdline_calls) {
343
struct mapitest_unit *el;
345
for (el = mt.cmdline_calls; el; el = el->next) {
346
printf("[*] %s\n", el->name);
347
mapitest_run_test(&mt, el->name);
350
mapitest_run_all(&mt);
353
num_tests_failed = mapitest_stat_dump(&mt);
355
mapitest_cleanup_stream(&mt);
357
/* Uninitialize and free memory */
358
MAPIUninitialize(mt.mapi_ctx);
359
talloc_free(mt.mem_ctx);
361
if (opt_leak_report) {
362
talloc_report(NULL, stdout);
365
if (opt_leak_report_full) {
366
talloc_report_full(NULL, stdout);
369
return num_tests_failed;