ac2edd8895477930e1ed850c8ceba1c8f55d4263
[tridge/openchange.git] / branches / plugfest / utils / mapitest / mapitest_stat.c
1 /*
2    Stand-alone MAPI testsuite
3
4    OpenChange Project
5
6    Copyright (C) Julien Kerihuel 2008
7
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.
12    
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.
17    
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/>.
20 */
21
22 #include "utils/mapitest/mapitest.h"
23
24 #include <assert.h>
25
26 /**
27         \file
28         mapitest statistics functions
29
30         mapitest records and prints the results of each test
31         using these functions
32 */
33
34 /**
35   Descriptions of TestApplicabilityFlags
36 */
37 struct TestApplicabilityDescription {
38         enum TestApplicabilityFlags     flags;          /*!< The flag value */
39         char*                           description;    /*!< A user-visible string equivalent */
40 } applicabilityFlagsDescription[] = {
41         { ApplicableToAllVersions,      "Applicable to all server versions" },
42         { NotInExchange2010,            "Not applicable to Exchange 2010" },
43         { NotInExchange2010SP0,         "Not applicable to Exchange 2010 SP0" },
44         { LastTestApplicabilityFlag,    "Sentinel Value" }
45 };
46
47 /**
48    \details Initialize the mapitest statistic structure
49    
50    \param mem_ctx memory allocation context
51
52    \return Allocated stat structure on success, otherwise NULL
53  */
54 _PUBLIC_ struct mapitest_stat *mapitest_stat_init(TALLOC_CTX *mem_ctx)
55 {
56         struct mapitest_stat    *stat = NULL;
57
58         /* Sanity check */
59         if (!mem_ctx) return NULL;
60
61         stat = talloc_zero(mem_ctx, struct mapitest_stat);
62         stat->success = 0;
63         stat->failure = 0;
64         stat->skipped = 0;
65         stat->x_fail = 0;
66         stat->failure_info = NULL;
67         stat->skip_info = NULL;
68         stat->enabled = false;
69
70         return stat;
71 }
72
73
74 /**
75    \details Add test result to the suite statistic parameter
76
77    \param suite the suite container
78    \param name the test name
79    \param testresult the test result
80
81    \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR
82  */
83 _PUBLIC_ uint32_t mapitest_stat_add_result(struct mapitest_suite *suite,
84                                            const char *name,
85                                            enum TestResult testresult)
86 {
87         struct mapitest_unit    *el = NULL;
88
89         /* Sanity check */
90         if (!suite || !suite->stat || !name) return MAPITEST_ERROR;
91
92         if (testresult == Pass) {
93                 suite->stat->success++;
94         } else {
95                 el = talloc_zero((TALLOC_CTX *) suite->stat, struct mapitest_unit);
96                 el->name = talloc_strdup((TALLOC_CTX *)el, (char *)name);
97
98                 if (testresult == Fail) {
99                         suite->stat->failure++;
100                         el->reason = talloc_strdup((TALLOC_CTX *) el, "Unexpected Fail");
101                 } else if (testresult == ExpectedFailure) {
102                         suite->stat->x_fail++;
103                         el->reason = talloc_strdup((TALLOC_CTX *) el, "Expected Fail");
104                 } else if (testresult == UnexpectedPass) {
105                         suite->stat->failure++;
106                         el->reason = talloc_strdup((TALLOC_CTX *) el, "Unexpected Pass");
107                 } else {
108                         assert(0); /* this indicates that we're passing a bad enum into this function */
109                 }
110                 DLIST_ADD_END(suite->stat->failure_info, el, struct mapitest_unit *);
111         }
112
113         suite->stat->enabled = true;
114
115         return MAPITEST_SUCCESS;
116 }
117
118 static void mapitest_stat_add_skipped_test_reason(struct mapitest_unit *stat_unit, enum TestApplicabilityFlags flags)
119 {
120         int i;
121         for (i = 0; applicabilityFlagsDescription[i].flags != LastTestApplicabilityFlag; ++i) {
122                 if (flags & applicabilityFlagsDescription[i].flags) {
123                         if (!stat_unit->reason) {
124                                 stat_unit->reason = talloc_strdup((TALLOC_CTX *)stat_unit, applicabilityFlagsDescription[i].description);
125                         } else {
126                                 stat_unit->reason = talloc_asprintf_append(stat_unit->reason, ", %s", applicabilityFlagsDescription[i].description);
127                         }
128                 }
129         }
130         if (!stat_unit->reason) {
131                 stat_unit->reason = talloc_strdup((TALLOC_CTX *)stat_unit, "Unknown reason");
132         }
133 }
134
135 /**
136    \details Add a skipped test to the suite statistic parameters
137
138    \param suite the suite container
139    \param name the test name
140    \param flags flags to indicate the reason why the test was skipped
141
142    \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR
143  */
144 _PUBLIC_ uint32_t mapitest_stat_add_skipped_test(struct mapitest_suite *suite,
145                                                  const char *name,
146                                                  enum TestApplicabilityFlags flags)
147 {
148         struct mapitest_unit    *el = NULL;
149
150         /* Sanity check */
151         if (!suite || !suite->stat || !name) return MAPITEST_ERROR;
152
153         suite->stat->skipped++;
154         el = talloc_zero((TALLOC_CTX *) suite->stat, struct mapitest_unit);
155         el->name = talloc_strdup((TALLOC_CTX *)el, (char *)name);
156         mapitest_stat_add_skipped_test_reason(el, flags);
157         DLIST_ADD_END(suite->stat->skip_info, el, struct mapitest_unit *);
158
159         suite->stat->enabled = true;
160
161         return MAPITEST_SUCCESS;
162 }
163
164 /**
165    \details Dump mapitest statistics about test failures
166
167    \param mt the global mapitest structure
168
169    \return the number of test steps that failed (i.e. 0 for all success)
170  */
171 _PUBLIC_ int32_t mapitest_stat_dump(struct mapitest *mt)
172 {
173         struct mapitest_suite   *suite;
174         struct mapitest_unit    *el;
175         int32_t                 num_passed_tests = 0;
176         int32_t                 num_failed_tests = 0;
177         int32_t                 num_skipped_tests = 0;
178         int32_t                 num_xfail_tests = 0;
179
180         mapitest_print_title(mt, MT_STAT_SKIPPED_TITLE, MODULE_TITLE_DELIM);
181         for (suite = mt->mapi_suite; suite; suite = suite->next) {
182                 if (suite->stat->enabled == true) {
183                         num_skipped_tests += suite->stat->skipped;
184                         if (suite->stat->skipped) {
185                                 for (el = suite->stat->skip_info; el; el = el->next) {
186                                         mapitest_print(mt, MT_STAT_RESULT, suite->name, el->name, el->reason);
187                                 }
188                         }
189                 }
190         }
191
192         mapitest_print_test_title_end(mt);
193
194         mapitest_print_title(mt, MT_STAT_FAILED_TITLE, MODULE_TITLE_DELIM);
195
196         for (suite = mt->mapi_suite; suite; suite = suite->next) {
197                 if (suite->stat->enabled == true) {
198                         num_passed_tests += suite->stat->success;
199                         num_failed_tests += suite->stat->failure;
200                         num_xfail_tests += suite->stat->x_fail;
201                         if (suite->stat->failure || suite->stat->x_fail) {
202                                 for (el = suite->stat->failure_info; el; el = el->next) {
203                                         mapitest_print(mt, MT_STAT_RESULT, suite->name, el->name, el->reason);
204                                 }
205                         }
206                 }
207         }
208
209         mapitest_print_test_title_end(mt);
210
211         mapitest_print_title(mt, MT_SUMMARY_TITLE, MODULE_TITLE_DELIM);
212         mapitest_print(mt, "Number of passing tests: %i\n", num_passed_tests);
213         mapitest_print(mt, "Number of failing tests: %i\n", num_failed_tests);
214         mapitest_print(mt, "Number of skipped tests: %i\n", num_skipped_tests);
215         mapitest_print(mt, "Number of expected fails: %i\n", num_xfail_tests);
216         mapitest_print_test_title_end(mt);
217
218         return num_failed_tests;
219 }