00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <time.h>
00027 #include <stdio.h>
00028 #include <errno.h>
00029 #include <string.h>
00030 #include <libxml/xmlwriter.h>
00031 #include "testresultlogger.h"
00032 #include "log.h"
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 LOCAL xmlTextWriterPtr writer;
00061 LOCAL FILE *ofile;
00062
00063
00064
00065
00066
00067
00068 struct
00069 {
00070 int (*write_pre_suite_tag) (td_suite *);
00071 int (*write_post_suite_tag) (void);
00072 int (*write_pre_set_tag) (td_set *);
00073 int (*write_post_set_tag) (td_set *);
00074 } out_cbs;
00075
00076
00077
00078 LOCAL int xml_write_pre_suite_tag (td_suite *);
00079
00080 LOCAL int xml_write_pre_set_tag (td_set *);
00081
00082 LOCAL int xml_write_step (const void *, const void *);
00083
00084 LOCAL int xml_write_case (const void *, const void *);
00085
00086 LOCAL int xml_write_post_set_tag (td_set *);
00087
00088 LOCAL int txt_write_pre_suite_tag (td_suite *);
00089
00090 LOCAL int txt_write_post_suite_tag ();
00091
00092 LOCAL int txt_write_pre_set_tag (td_set *);
00093
00094 LOCAL int txt_write_post_set_tag (td_set *);
00095
00096 LOCAL int txt_write_case (const void *, const void *);
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00111 LOCAL int xml_write_pre_suite_tag (td_suite *suite)
00112 {
00113
00114 if (xmlTextWriterStartElement (writer, BAD_CAST "suite") < 0)
00115 goto err_out;
00116
00117 if (xmlTextWriterWriteAttribute (writer, BAD_CAST "name",
00118 suite->gen.name) < 0)
00119 goto err_out;
00120
00121 if (suite->gen.domain && xmlTextWriterWriteAttribute (writer,
00122 BAD_CAST
00123 "domain",
00124 suite->gen.domain) < 0)
00125 goto err_out;
00126
00127 return 0;
00128 err_out:
00129 return 1;
00130 }
00131
00136 LOCAL int xml_write_pre_set_tag (td_set *set)
00137 {
00138 if (xmlTextWriterStartElement (writer, BAD_CAST "set") < 0)
00139 goto err_out;
00140
00141 if (xmlTextWriterWriteAttribute (writer,
00142 BAD_CAST "name",
00143 set->gen.name) < 0)
00144 goto err_out;
00145
00146 if (set->gen.description)
00147 if (xmlTextWriterWriteAttribute (writer,
00148 BAD_CAST "description",
00149 set->gen.description) < 0)
00150 goto err_out;
00151
00152 if (set->gen.feature)
00153 if (xmlTextWriterWriteAttribute (writer,
00154 BAD_CAST "feature",
00155 set->gen.feature) < 0)
00156 goto err_out;
00157
00158 if (set->environment)
00159 if (xmlTextWriterWriteAttribute (writer,
00160 BAD_CAST "environment",
00161 set->environment) < 0)
00162 goto err_out;
00163 return 0;
00164 err_out:
00165 return 1;
00166 }
00167
00173 LOCAL int xml_write_step (const void *data, const void *user)
00174 {
00175 td_step *step = (td_step *)data;
00176 struct tm *tm;
00177
00178 if (xmlTextWriterStartElement (writer, BAD_CAST "step") < 0)
00179 goto err_out;
00180
00181 if (xmlTextWriterWriteAttribute (writer,
00182 BAD_CAST "command",
00183 step->step) < 0)
00184 goto err_out;
00185
00186 if (step->has_result == 0) {
00187 if (xmlTextWriterWriteAttribute (writer,
00188 BAD_CAST "result",
00189 BAD_CAST "N/A") < 0)
00190 goto err_out;
00191
00192
00193 } else if (xmlTextWriterWriteAttribute (writer,
00194 BAD_CAST "result",
00195 step->expected_result ==
00196 step->return_code ?
00197 BAD_CAST "PASS" :
00198 BAD_CAST "FAIL") < 0)
00199 goto err_out;
00200
00201 if (step->failure_info) {
00202 if (strlen ((char *)step->failure_info) >= FAILURE_INFO_MAX)
00203 step->failure_info[FAILURE_INFO_MAX - 1] = '\0';
00204 if (xmlTextWriterWriteAttribute (writer,
00205 BAD_CAST "failure_info",
00206 step->failure_info) < 0)
00207 goto err_out;
00208 }
00209
00210 if (xmlTextWriterWriteFormatElement (writer,
00211 BAD_CAST "expected_result",
00212 "%d", step->expected_result) < 0)
00213 goto err_out;
00214
00215 if (xmlTextWriterWriteFormatElement (writer,
00216 BAD_CAST "return_code",
00217 "%d", step->return_code) < 0)
00218 goto err_out;
00219
00220 tm = localtime (&step->start);
00221 if (xmlTextWriterWriteFormatElement (writer,
00222 BAD_CAST "start",
00223 "%02d-%02d-%02d %02d:%02d:%02d",
00224 tm->tm_year+1900,
00225 tm->tm_mon+1,
00226 tm->tm_mday,
00227 tm->tm_hour,
00228 tm->tm_min,
00229 tm->tm_sec) < 0)
00230 goto err_out;
00231
00232 tm = localtime (&step->end);
00233 if (xmlTextWriterWriteFormatElement (writer,
00234 BAD_CAST "end",
00235 "%02d-%02d-%02d %02d:%02d:%02d",
00236 tm->tm_year+1900,
00237 tm->tm_mon+1,
00238 tm->tm_mday,
00239 tm->tm_hour,
00240 tm->tm_min,
00241 tm->tm_sec) < 0)
00242 goto err_out;
00243
00244 if (step->stdout_)
00245 if (xmlTextWriterWriteFormatElement (writer,
00246 BAD_CAST "stdout",
00247 "%s",
00248 step->stdout_) < 0)
00249 goto err_out;
00250
00251 if (step->stderr_)
00252 if (xmlTextWriterWriteFormatElement (writer,
00253 BAD_CAST "stderr",
00254 "%s",
00255 step->stderr_) < 0)
00256 goto err_out;
00257
00258
00259 xml_end_element();
00260
00261
00262 return 1;
00263
00264 err_out:
00265 return 0;
00266 }
00267
00273 LOCAL int xml_write_case (const void *data, const void *user)
00274 {
00275 td_case *c = (td_case *)data;
00276
00277 if (c->filtered)
00278 return 1;
00279
00280 if (xmlTextWriterStartElement (writer, BAD_CAST "case") < 0)
00281 goto err_out;
00282
00283 if (xmlTextWriterWriteAttribute (writer,
00284 BAD_CAST "name",
00285 c->gen.name) < 0)
00286 goto err_out;
00287
00288 if (c->gen.description)
00289 if (xmlTextWriterWriteAttribute (writer,
00290 BAD_CAST "description",
00291 c->gen.description) < 0)
00292 goto err_out;
00293
00294 if (xmlTextWriterWriteAttribute (writer,
00295 BAD_CAST "manual",
00296 BAD_CAST (c->gen.manual ? "true" :
00297 "false")) < 0)
00298 goto err_out;
00299
00300 if (xmlTextWriterWriteAttribute (writer,
00301 BAD_CAST "insignificant",
00302 BAD_CAST (c->gen.insignificant ?
00303 "true" :
00304 "false")) < 0)
00305 goto err_out;
00306
00307
00308 if (xmlTextWriterWriteAttribute (writer,
00309 BAD_CAST "result",
00310 BAD_CAST (case_result_str
00311 (c->case_res))) < 0)
00312
00313 goto err_out;
00314
00315 if (c->failure_info) {
00316 if (strlen ((char *)c->failure_info) >= FAILURE_INFO_MAX)
00317 c->failure_info[FAILURE_INFO_MAX - 1] = '\0';
00318 if (xmlTextWriterWriteAttribute (writer,
00319 BAD_CAST "failure_info",
00320 c->failure_info) < 0)
00321 goto err_out;
00322 }
00323
00324 if (c->subfeature)
00325 if (xmlTextWriterWriteAttribute (writer,
00326 BAD_CAST "subfeature",
00327 c->subfeature) < 0)
00328 goto err_out;
00329
00330 if (c->gen.requirement)
00331 if (xmlTextWriterWriteAttribute (writer,
00332 BAD_CAST "requirement",
00333 c->gen.requirement) < 0)
00334 goto err_out;
00335
00336 if (c->gen.level)
00337 if (xmlTextWriterWriteAttribute (writer,
00338 BAD_CAST "level",
00339 c->gen.level) < 0)
00340 goto err_out;
00341
00342 if (c->gen.manual && c->comment)
00343 if (xmlTextWriterWriteAttribute (writer,
00344 BAD_CAST "comment",
00345 c->comment) < 0)
00346 goto err_out;
00347
00348
00349 xmlListWalk (c->steps, xml_write_step, NULL);
00350
00351 xml_end_element ();
00352
00353 return 1;
00354
00355 err_out:
00356 LOG_MSG (LOG_ERR, "%s:%s: error\n", PROGNAME, __FUNCTION__);
00357
00358 return 0;
00359 }
00360
00365 LOCAL int xml_write_post_set_tag (td_set *set)
00366 {
00367
00368
00369 xmlListWalk (set->cases, xml_write_case, NULL);
00370
00371 return 0;
00372 }
00373
00374
00375
00381 LOCAL int txt_write_step (const void *data, const void *user)
00382 {
00383 td_step *step = (td_step *)data;
00384 struct tm *tm;
00385 fprintf (ofile, "----------------------------------"
00386 "----------------------------------\n");
00387 fprintf (ofile, " Test step : %s\n", step->step);
00388 tm = localtime (&step->start);
00389
00390 fprintf (ofile, " start : %02d-%02d-%02d"
00391 " %02d:%02d:%02d\n",
00392 tm->tm_year+1900,
00393 tm->tm_mon+1,
00394 tm->tm_mday,
00395 tm->tm_hour,
00396 tm->tm_min,
00397 tm->tm_sec);
00398 tm = localtime (&step->end);
00399 fprintf (ofile, " end : %02d-%02d-%02d"
00400 " %02d:%02d:%02d\n",
00401 tm->tm_year+1900,
00402 tm->tm_mon+1,
00403 tm->tm_mday,
00404 tm->tm_hour,
00405 tm->tm_min,
00406 tm->tm_sec);
00407 fprintf (ofile, " expected code : %d\n", step->expected_result);
00408 fprintf (ofile, " return code : %d\n", step->return_code);
00409 fprintf (ofile, " result : %s %s\n",
00410 (step->return_code == step->expected_result ? "PASS" : "FAIL"),
00411 (step->failure_info ? (char *)step->failure_info : " "));
00412 fprintf (ofile, " stdout : %s\n",
00413 step->stdout_ ? (char *)step->stdout_ : " ");
00414 fprintf (ofile, " stderr : %s\n",
00415 step->stderr_ ? (char *)step->stderr_ : " ");
00416 fflush (ofile);
00417
00418 return 1;
00419 }
00420
00426 LOCAL int txt_write_case (const void *data, const void *user)
00427 {
00428 td_case *c = (td_case *)data;
00429
00430 if (c->filtered)
00431 return 1;
00432
00433 fprintf (ofile, "----------------------------------"
00434 "----------------------------------\n");
00435 fprintf (ofile, " Test case name : %s\n", c->gen.name);
00436 fprintf (ofile, " description : %s\n", c->gen.description ?
00437 (char *)c->gen.description : "");
00438 fprintf (ofile, " manual : %s\n", c->gen.manual ?
00439 "true" : "false");
00440 fprintf (ofile, " result : %s",
00441 case_result_str(c->case_res));
00442 if (c->failure_info) {
00443 fprintf (ofile, " (%s)", c->failure_info);
00444 }
00445 fprintf (ofile, "\n");
00446
00447 if (c->gen.requirement)
00448 fprintf (ofile, " requirement : %s\n", c->gen.requirement);
00449 if (c->subfeature)
00450 fprintf (ofile, " subfeature : %s\n", c->subfeature);
00451 #if 0
00452 if (c->gen.type)
00453 fprintf (ofile, " type : %s\n", c->gen.type);
00454 #endif
00455 if (c->gen.level)
00456 fprintf (ofile, " level : %s\n", c->gen.level);
00457
00458 fprintf (ofile, " insignificant : %s\n", c->gen.insignificant ?
00459 "true" : "false");
00460
00461
00462 if (c->gen.manual && c->comment)
00463 fprintf (ofile, " comment : %s\n", c->comment);
00464
00465 fflush (ofile);
00466
00467 xmlListWalk (c->steps, txt_write_step, NULL);
00468
00469
00470 return 1;
00471 }
00476 LOCAL int txt_write_pre_suite_tag (td_suite *suite)
00477 {
00478 fprintf (ofile, "----------------------------------"
00479 "----------------------------------\n");
00480
00481 fprintf (ofile, "Test suite name : %s\n", suite->gen.name);
00482 fprintf (ofile, " description : %s\n", suite->gen.description ?
00483 (char *)suite->gen.description : " ");
00484 if (suite->gen.domain)
00485 fprintf (ofile, " domain : %s\n", suite->gen.domain);
00486
00487 fflush (ofile);
00488
00489 return 0;
00490 }
00491
00495 LOCAL int txt_write_post_suite_tag ()
00496 {
00497 return 0;
00498
00499 }
00500
00505 LOCAL int txt_write_pre_set_tag (td_set *set)
00506 {
00507 fprintf (ofile, "----------------------------------"
00508 "----------------------------------\n");
00509
00510 fprintf (ofile, " Test set name : %s\n", set->gen.name);
00511 fprintf (ofile, " description : %s\n", set->gen.description ?
00512 (char *)set->gen.description : "");
00513 if (set->gen.feature)
00514 fprintf (ofile, " feature : %s\n", set->gen.feature);
00515
00516 fprintf (ofile, " environment : %s\n", set->environment ?
00517 (char *)set->environment : "");
00518
00519 fflush (ofile);
00520 return 0;
00521
00522 }
00523
00528 LOCAL int txt_write_post_set_tag (td_set *set)
00529 {
00530
00531 xmlListWalk (set->cases, txt_write_case, NULL);
00532 fflush (ofile);
00533
00534 return 0;
00535 }
00536
00537
00538
00544 int init_result_logger (testrunner_lite_options *opts, hw_info *hwinfo)
00545 {
00546
00547 switch (opts->output_type) {
00548 case OUTPUT_TYPE_XML:
00549
00550
00551
00552 writer = xmlNewTextWriterFilename(opts->output_filename, 0);
00553 if (!writer) {
00554 LOG_MSG (LOG_ERR, "%s:%s:failed to create writer for %s\n",
00555 PROGNAME, __FUNCTION__, opts->output_filename);
00556 return 1;
00557 }
00558 xmlTextWriterSetIndent (writer, 1);
00559 if (xmlTextWriterStartDocument(writer,
00560 "1.0",
00561 "UTF-8",
00562 NULL) < 0) {
00563 LOG_MSG (LOG_ERR, "%s:%s:failed to write document start\n",
00564 PROGNAME, __FUNCTION__);
00565 return 1;
00566 }
00567
00568 if (xmlTextWriterStartElement (writer, BAD_CAST "testresults")
00569 < 0) {
00570 LOG_MSG (LOG_ERR, "%s:%s:failed to write testsresults tag\n",
00571 PROGNAME, __FUNCTION__);
00572 return 1;
00573 }
00574 if (xmlTextWriterWriteAttribute (writer,
00575 BAD_CAST "version",
00576 BAD_CAST "1.0") < 0)
00577 return 1;
00578
00579 if (xmlTextWriterWriteAttribute (writer,
00580 BAD_CAST "environment",
00581 BAD_CAST (opts->environment ?
00582 opts->environment :
00583 "unknown")) < 0)
00584 return 1;
00585
00586
00587 if (xmlTextWriterWriteAttribute (writer,
00588 BAD_CAST "hwproduct",
00589 (hwinfo->product ?
00590 hwinfo->product :
00591 BAD_CAST "unknown")) < 0)
00592 return 1;
00593
00594
00595
00596 if (xmlTextWriterWriteAttribute (writer,
00597 BAD_CAST "hwbuild",
00598 (hwinfo->hw_build ?
00599 hwinfo->hw_build :
00600 BAD_CAST "unknown")) < 0)
00601 return 1;
00602
00603
00604
00605
00606
00607 out_cbs.write_pre_suite_tag = xml_write_pre_suite_tag;
00608 out_cbs.write_post_suite_tag = xml_end_element;
00609 out_cbs.write_pre_set_tag = xml_write_pre_set_tag;
00610 out_cbs.write_post_set_tag = xml_write_post_set_tag;
00611
00612
00613 break;
00614
00615 case OUTPUT_TYPE_TXT:
00616
00617
00618
00619 ofile = fopen (opts->output_filename, "w+");
00620 if (!ofile) {
00621 LOG_MSG (LOG_ERR, "%s:%s:failed to open file %s %s\n",
00622 PROGNAME, __FUNCTION__, opts->output_filename,
00623 strerror(errno));
00624 return 1;
00625 }
00626 fprintf (ofile,"Test results:\n");
00627 fprintf (ofile, " environment : %s\n", opts->environment);
00628
00629 fprintf (ofile, " hwproduct : %s\n",
00630 (char *)(hwinfo->product ? hwinfo->product :
00631 (unsigned char *)"unknown"));
00632
00633 fprintf (ofile, " hwbuild : %s\n",
00634 (char *)(hwinfo->hw_build ? hwinfo->hw_build :
00635 (unsigned char *)"unknown"));
00636
00637
00638
00639
00640
00641 out_cbs.write_pre_suite_tag = txt_write_pre_suite_tag;
00642 out_cbs.write_post_suite_tag = txt_write_post_suite_tag;
00643 out_cbs.write_pre_set_tag = txt_write_pre_set_tag;
00644 out_cbs.write_post_set_tag = txt_write_post_set_tag;
00645
00646 break;
00647
00648 default:
00649 LOG_MSG (LOG_ERR, "%s:%s:invalid output type %d\n",
00650 PROGNAME, __FUNCTION__, opts->output_type);
00651 return 1;
00652 }
00653
00654 return 0;
00655 }
00656
00661 int write_pre_suite_tag (td_suite *suite)
00662 {
00663 return out_cbs.write_pre_suite_tag (suite);
00664 }
00665
00670 int write_post_suite_tag (td_suite *suite)
00671 {
00672
00673 return out_cbs.write_post_suite_tag ();
00674 }
00675
00680 int write_pre_set_tag (td_set *set)
00681 {
00682 return out_cbs.write_pre_set_tag (set);
00683 }
00684
00689 int write_post_set_tag (td_set *set)
00690 {
00691
00692 return out_cbs.write_post_set_tag (set);
00693 }
00694
00698 int xml_end_element ()
00699 {
00700
00701 if (xmlTextWriterFullEndElement (writer) < 0)
00702 goto err_out;
00703 return 0;
00704 err_out:
00705 return 1;
00706 }
00707
00710 void close_result_logger (void)
00711 {
00712 if (writer) {
00713 xml_end_element();
00714 xmlTextWriterFlush (writer);
00715 xmlFreeTextWriter (writer);
00716 writer = NULL;
00717 } else if (ofile) {
00718 fprintf (ofile, "----------------------------------"
00719 "----------------------------------\n");
00720 fprintf (ofile, "End of test results.\n");
00721 fflush (ofile);
00722 fclose (ofile);
00723 ofile = NULL;
00724 } else {
00725 LOG_MSG (LOG_ERR, "%s:%s: Result logger not open?\n",
00726 PROGNAME, __FUNCTION__);
00727 }
00728
00729 return;
00730 }
00731
00732
00733
00734
00735