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"
27 mapitest test suite functions
31 \details Initialize a mapitest suite
33 \param mt the top-level mapitest structure
34 \param name the suite name
35 \param description the suite description
36 \param online whether this suite requires online (server) access
38 \return An allocated mapitest_suite pointer, otherwise NULL.
40 _PUBLIC_ struct mapitest_suite *mapitest_suite_init(struct mapitest *mt,
42 const char *description,
45 struct mapitest_suite *suite = NULL;
48 if (!mt || !mt->mem_ctx) return NULL;
49 if (!name) return NULL;
51 suite = talloc_zero(mt->mem_ctx, struct mapitest_suite);
53 suite->stat = mapitest_stat_init((TALLOC_CTX *)suite);
55 suite->name = talloc_strdup((TALLOC_CTX *) suite, name);
57 suite->description = NULL;
59 suite->description = talloc_strdup((TALLOC_CTX *)suite, description);
62 suite->online = online;
69 \details Register a mapitest suite
71 \param mt the top-level mapitest structure
72 \param suite the mapitest suite we want to add
74 \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR
76 \sa mapitest_suite_init
78 _PUBLIC_ uint32_t mapitest_suite_register(struct mapitest *mt,
79 struct mapitest_suite *suite)
81 struct mapitest_suite *el = NULL;
84 if (!mt || !mt->mem_ctx) return MAPITEST_ERROR;
85 if (!suite) return MAPITEST_ERROR;
87 /* Ensure the name is not yet registered */
88 for (el = mt->mapi_suite; el; el = el->next) {
89 if (el->name && !strcmp(el->name, suite->name)) {
90 fprintf(stderr, "Suite already registered\n");
91 return MAPITEST_ERROR;
95 DLIST_ADD_END(mt->mapi_suite, suite, struct mapitest_suite *);
97 return MAPITEST_SUCCESS;
101 \details add a test to the mapitest suite with description
103 \param suite pointer on the parent suite
104 \param name the test name
105 \param description the test description
106 \param run the test function
108 \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR
110 \sa mapitest_suite_init, mapitest_suite_register
111 \sa mapitest_suite_add_test_flagged for an alternative function allowing the
112 test to only be run under some conditions.
114 _PUBLIC_ uint32_t mapitest_suite_add_test(struct mapitest_suite *suite,
115 const char *name, const char *description,
116 bool (*run) (struct mapitest *test))
118 return mapitest_suite_add_test_flagged(suite, name, description, run, ApplicableToAllVersions);
122 \details add a test to the mapitest suite with description and flags
124 This is very similar to mapitest_suite_add_test(), except it allows a test to have
125 special applicability (e.g. to only run when a particular server configuration is available).
127 \param suite pointer to the parent test suite
128 \param name the test name
129 \param description the test description
130 \param run the test function
131 \param applicability a set of applicability flags
133 \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR
135 \sa mapitest_suite_init, mapitest_suite_register, mapitest_suite_add_test
137 _PUBLIC_ uint32_t mapitest_suite_add_test_flagged(struct mapitest_suite *suite,
138 const char *name, const char *description,
139 bool (*run) (struct mapitest *test),
140 enum TestApplicabilityFlags applicability)
142 struct mapitest_test *el = NULL;
145 if (!suite || !name || !run || !description) return MAPITEST_ERROR;
147 /* Ensure the test is not yet registered */
148 for (el = suite->tests; el; el = el->next) {
149 if (el->name && !strcmp(el->name, name)) {
150 return MAPITEST_ERROR;
154 el = talloc_zero((TALLOC_CTX *) suite, struct mapitest_test);
155 el->name = talloc_asprintf((TALLOC_CTX *)suite, "%s-%s", suite->name, name);
156 el->description = talloc_strdup((TALLOC_CTX *)suite, description);
158 el->flags = applicability;
160 DLIST_ADD_END(suite->tests, el, struct mapitest_test *);
162 return MAPITEST_SUCCESS;
167 \details Find a suite given its name
169 \param mt top-level mapitest structure
170 \param name the suite name to be searched
172 \return Pointer on a suite on success, otherwise NULL
174 _PUBLIC_ struct mapitest_suite *mapitest_suite_find(struct mapitest *mt,
177 struct mapitest_suite *suite = NULL;
179 if (!name) return NULL;
181 for (suite = mt->mapi_suite; suite; suite = suite->next) {
182 if (!strcmp(name, suite->name)) {
191 \details test whether a particular test is applicable
193 \param mt pointer to the top-level mapitest structure
194 \param el the test to check
196 \return true if the test should be run, otherwise false
198 static bool mapitest_suite_test_is_applicable(struct mapitest *mt, struct mapitest_test *test)
200 uint16_t actualServerVer = mt->info.rgwServerVersion[0];
202 if ((test->flags & NotInExchange2010) && (actualServerVer >= Exchange2010SP0Version)) {
205 if ((test->flags & NotInExchange2010SP0) && (actualServerVer == Exchange2010SP0Version)) {
211 static bool run_test(struct mapitest *mt, struct mapitest_suite *suite, struct mapitest_test *el)
213 bool (*fn)(struct mapitest *);
216 if (!mapitest_suite_test_is_applicable(mt, el)) {
217 mapitest_stat_add_skipped_test(suite, el->name, el->flags);
220 mapitest_print_test_title_start(mt, el->name);
225 if (el->flags & ExpectedFail) {
227 mapitest_stat_add_result(suite, el->name, UnexpectedPass);
229 mapitest_stat_add_result(suite, el->name, ExpectedFailure);
233 mapitest_stat_add_result(suite, el->name, Pass);
235 mapitest_stat_add_result(suite, el->name, Fail);
238 mapitest_print_test_title_end(mt);
239 mapitest_print_test_result(mt, el->name, ret);
245 \details run a test from a suite given its name
247 \param mt pointer on the top-level mapitest structure
248 \param suite pointer on the mapitest suite
249 \param name the name of the test to be run
251 \return true on success, otherwise false
253 _PUBLIC_ bool mapitest_suite_run_test(struct mapitest *mt,
254 struct mapitest_suite *suite,
257 struct mapitest_test *el;
260 if (!suite || !name) return false;
262 for (el = suite->tests; el; el = el->next) {
263 if (!strcmp(el->name, name)) {
264 ret = run_test(mt, suite, el);
269 fprintf(stderr, "[ERROR] %s test doesn't exist\n", name);
275 \details run the special SUITE-ALL test
277 \param mt the top-level mapitest structure
278 \param name the mapitest test name
280 \return true on success, otherwise -1
282 static bool mapitest_run_test_all(struct mapitest *mt, const char *name)
287 struct mapitest_test *el;
288 struct mapitest_suite *suite;
291 test_name = talloc_strdup(mt->mem_ctx, name);
292 if ((tmp = strtok(test_name, "-")) == NULL) {
293 talloc_free(test_name);
296 sname = talloc_strdup(mt->mem_ctx, tmp);
297 if ((tmp = strtok(NULL, "-")) == NULL) {
298 talloc_free(test_name);
303 if (!strcmp(tmp,"ALL")) {
304 suite = mapitest_suite_find(mt, sname);
306 if ((suite && (suite->online == mt->online)) || (suite && (suite->online == false))) {
307 for (el = suite->tests; el; el = el->next) {
308 if (mapitest_suite_test_is_applicable(mt, el)) {
309 mapitest_suite_run_test(mt, suite, el->name);
312 printf("test is not applicable: %s\n", el->name);
319 talloc_free(test_name);
325 \details run a specific test from a particular suite
327 \param mt the top-level mapitest structure
328 \param name the mapitest test name
330 \return true on success, otherwise -1
332 _PUBLIC_ bool mapitest_run_test(struct mapitest *mt, const char *name)
334 struct mapitest_suite *suite;
335 struct mapitest_test *el;
339 if (!mt || !name) return false;
341 /* try to find the test */
342 for (suite = mt->mapi_suite; suite; suite = suite->next) {
343 for (el = suite->tests; el; el = el->next) {
344 if (!strcmp(name, el->name)) {
345 if (((mt->online == suite->online) && mt->session) || (suite->online == false)) {
347 ret = mapitest_suite_run_test(mt, suite, name);
350 fprintf(stderr, "Server is offline, skipping test: \"%s\"\n", name);
357 /* if no name matches, look it it matches ALL */
358 ret = mapitest_run_test_all(mt, name);
361 fprintf(stderr, "[ERROR] Unknown test: \"%s\"\n", name);
367 static void run_tests_in_suite(struct mapitest *mt, struct mapitest_suite *suite)
369 struct mapitest_test *el;
371 for (el = suite->tests; el; el = el->next) {
372 run_test(mt, suite, el);
377 \details all tests from all suites
379 \param mt the top-level mapitest structure
381 \return true on success, otherwise -1
383 _PUBLIC_ void mapitest_run_all(struct mapitest *mt)
385 struct mapitest_suite *suite;
387 for (suite = mt->mapi_suite; suite; suite = suite->next) {
388 if (((mt->online == suite->online) && mt->session) || (suite->online == false)) {
389 mapitest_print_module_title_start(mt, suite->name);
391 run_tests_in_suite(mt, suite);
393 mapitest_print_module_title_end(mt);