* [ptest-runner][PATCHv2 1/2] utils, main: pass opts struct to run_ptests @ 2017-02-01 15:42 Pascal Bach 2017-02-01 15:42 ` [ptest-runner][PATCHv2 2/2] Add xml output Pascal Bach 0 siblings, 1 reply; 3+ messages in thread From: Pascal Bach @ 2017-02-01 15:42 UTC (permalink / raw) To: yocto This allows to easily add additional parameters Signed-off-by: Pascal Bach <pascal.bach@siemens.com> --- main.c | 10 ++-------- tests/utils.c | 14 ++++++++++---- utils.c | 4 ++-- utils.h | 9 ++++++++- 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/main.c b/main.c index 31bf3b5..765d688 100644 --- a/main.c +++ b/main.c @@ -45,13 +45,6 @@ print_usage(FILE *stream, char *progname) "[-h] [ptest1 ptest2 ...]\n", progname); } -static struct { - char *directory; - int list; - int timeout; - char **ptests; -} opts; - int main(int argc, char *argv[]) { @@ -66,6 +59,7 @@ main(int argc, char *argv[]) struct ptest_list *head, *run; + struct options opts; opts.directory = strdup(DEFAULT_DIRECTORY); opts.list = 0; opts.timeout = DEFAULT_TIMEOUT; @@ -133,7 +127,7 @@ main(int argc, char *argv[]) ptest_list_free_all(head); } - rc = run_ptests(run, opts.timeout, argv[0], stdout, stderr); + rc = run_ptests(run, opts, argv[0], stdout, stderr); ptest_list_free_all(run); diff --git a/tests/utils.c b/tests/utils.c index 1332798..6b70c2e 100644 --- a/tests/utils.c +++ b/tests/utils.c @@ -51,6 +51,8 @@ static char *ptests_not_found[] = { NULL, }; +static struct options EmptyOpts; + static inline void find_word(int *found, const char *line, const char *word) { @@ -153,8 +155,9 @@ START_TEST(test_filter_ptests) END_TEST START_TEST(test_run_ptests) - struct ptest_list *head; - int timeout = 1; + struct ptest_list *head; + struct options opts = EmptyOpts; + opts.timeout = 1; int rc; char *buf_stdout; @@ -173,7 +176,7 @@ START_TEST(test_run_ptests) ptest_list_remove(head, "hang", 1); ptest_list_remove(head, "fail", 1); - rc = run_ptests(head, timeout, "test_run_ptests", fp_stdout, fp_stderr); + rc = run_ptests(head, opts, "test_run_ptests", fp_stdout, fp_stderr); ck_assert(rc == 0); ptest_list_free_all(head); @@ -275,8 +278,11 @@ test_ptest_expected_failure(struct ptest_list *head, const int timeout, char *pr struct ptest_list *filtered = filter_ptests(head, &progname, 1); ck_assert(ptest_list_length(filtered) == 1); + struct options opts = EmptyOpts; + opts.timeout = timeout; + h_analizer( - run_ptests(filtered, timeout, progname, fp_stdout, fp_stderr), + run_ptests(filtered, opts, progname, fp_stdout, fp_stderr), fp_stdout, fp_stderr ); diff --git a/utils.c b/utils.c index 77427e0..48c1990 100644 --- a/utils.c +++ b/utils.c @@ -302,7 +302,7 @@ wait_child(const char *ptest_dir, const char *run_ptest, pid_t pid, } int -run_ptests(struct ptest_list *head, int timeout, const char *progname, +run_ptests(struct ptest_list *head, const struct options opts, const char *progname, FILE *fp, FILE *fp_stderr) { int rc = 0; @@ -350,7 +350,7 @@ run_ptests(struct ptest_list *head, int timeout, const char *progname, fprintf(fp, "BEGIN: %s\n", ptest_dir); status = wait_child(ptest_dir, p->run_ptest, child, - timeout, fds, fps); + opts.timeout, fds, fps); if (status) { fprintf(fp, "ERROR: Exit status is %d\n", status); rc += 1; diff --git a/utils.h b/utils.h index 4dc23ef..d7f5268 100644 --- a/utils.h +++ b/utils.h @@ -30,10 +30,17 @@ #define CHECK_ALLOCATION(p, size, exit_on_null) \ check_allocation1(p, size, __FILE__, __LINE__, exit_on_null) +struct options { + char *directory; + int list; + int timeout; + char **ptests; +}; + extern void check_allocation1(void *, size_t, char *, int, int); extern struct ptest_list *get_available_ptests(const char *); extern int print_ptests(struct ptest_list *, FILE *); extern struct ptest_list *filter_ptests(struct ptest_list *, char **, int); -extern int run_ptests(struct ptest_list *, int, const char *progname, FILE *, FILE *); +extern int run_ptests(struct ptest_list *, const struct options, const char *progname, FILE *, FILE *); #endif -- 2.1.4 ^ permalink raw reply related [flat|nested] 3+ messages in thread
* [ptest-runner][PATCHv2 2/2] Add xml output 2017-02-01 15:42 [ptest-runner][PATCHv2 1/2] utils, main: pass opts struct to run_ptests Pascal Bach @ 2017-02-01 15:42 ` Pascal Bach 2017-04-06 21:12 ` Aníbal Limón 0 siblings, 1 reply; 3+ messages in thread From: Pascal Bach @ 2017-02-01 15:42 UTC (permalink / raw) To: yocto; +Cc: Schuler Christian The format follow the one defined in the Yocto wiki: https://wiki.yoctoproject.org/wiki/QA/xUnit_XML_Template It is only the minimum required but it can be extended in the future. Signed-off-by: Schuler Christian <schuler.christian@siemens.com> Signed-off-by: Pascal Bach <pascal.bach@siemens.com> --- README.md | 1 + main.c | 13 ++++++++++--- tests/data/reference.xml | 8 ++++++++ tests/utils.c | 46 ++++++++++++++++++++++++++++++++++++++++++++ utils.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ utils.h | 10 ++++++++-- 6 files changed, 123 insertions(+), 5 deletions(-) create mode 100644 tests/data/reference.xml diff --git a/README.md b/README.md index ed7a589..fedab04 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ Now the ptest-runner2 support the next features: - List available ptests. - Specify the timeout for avoid blocking indefinetly. - Only run certain ptests. +- XML-ouput Proposed features: diff --git a/main.c b/main.c index 765d688..5f37541 100644 --- a/main.c +++ b/main.c @@ -41,7 +41,7 @@ static inline void print_usage(FILE *stream, char *progname) { - fprintf(stream, "Usage: %s [-d directory] [-l list] [-t timeout] " + fprintf(stream, "Usage: %s [-d directory] [-l list] [-t timeout] [-x xml-filename]" "[-h] [ptest1 ptest2 ...]\n", progname); } @@ -60,12 +60,14 @@ main(int argc, char *argv[]) struct ptest_list *head, *run; struct options opts; + opts.directory = strdup(DEFAULT_DIRECTORY); opts.list = 0; opts.timeout = DEFAULT_TIMEOUT; opts.ptests = NULL; + opts.xml_filename = NULL; - while ((opt = getopt(argc, argv, "d:lt:h")) != -1) { + while ((opt = getopt(argc, argv, "d:ltx:h")) != -1) { switch (opt) { case 'd': free(opts.directory); @@ -82,6 +84,11 @@ main(int argc, char *argv[]) print_usage(stdout, argv[0]); exit(0); break; + case 'x': + free(opts.xml_filename); + opts.xml_filename = strdup(optarg); + CHECK_ALLOCATION(opts.xml_filename, 1, 1); + break; default: print_usage(stdout, argv[0]); exit(1); @@ -125,7 +132,7 @@ main(int argc, char *argv[]) run = filter_ptests(head, opts.ptests, ptest_num); CHECK_ALLOCATION(run, ptest_num, 1); ptest_list_free_all(head); - } + } rc = run_ptests(run, opts, argv[0], stdout, stderr); diff --git a/tests/data/reference.xml b/tests/data/reference.xml new file mode 100644 index 0000000..0d858e1 --- /dev/null +++ b/tests/data/reference.xml @@ -0,0 +1,8 @@ +<?xml version='1.0' encoding='UTF-8'?> +<testsuite name='ptest' tests='2'> +<testcase classname='test1' name='run-ptest'> +</testcase> +<testcase classname='test2' name='run-ptest'> +<failure type='exit_code' message='run-ptest exited with code: 1'></failure> +</testcase> +</testsuite> diff --git a/tests/utils.c b/tests/utils.c index 6b70c2e..f5d3b62 100644 --- a/tests/utils.c +++ b/tests/utils.c @@ -237,6 +237,50 @@ START_TEST(test_run_fail_ptest) ptest_list_free_all(head); END_TEST +int filecmp(FILE *fp1, FILE *fp2) +{ + char f1, f2; + while (1) { + int end = 0; + if ((f1 = getc(fp1)) == EOF) end++; + if ((f2 = getc(fp2)) == EOF) end++; + + if (end == 2) return 0; + if (end == 1) return 1; + if (f1 != f2) return 2; + } +} + +START_TEST(test_xml_pass) + + + + XML *xp; + xp = xml_create(2, "./test.xml"); + ck_assert(xp != NULL); + xml_add_case(xp, 0,"test1"); + xml_add_case(xp, 1,"test2"); + xml_finish(xp); + + FILE *fp, *fr; + fr = fopen("./tests/data/reference.xml", "r"); + ck_assert(fr != NULL); + fp = fopen("./test.xml", "r"); + ck_assert(fp != NULL); + + ck_assert(filecmp(fr, fp) == 0); + + fclose(fr); + fclose(fp); + unlink("./test.xml"); + +END_TEST + +START_TEST(test_xml_fail) + ck_assert(xml_create(2, "./") == NULL); + +END_TEST + Suite * utils_suite() { @@ -252,6 +296,8 @@ utils_suite() tcase_add_test(tc_core, test_run_ptests); tcase_add_test(tc_core, test_run_timeout_ptest); tcase_add_test(tc_core, test_run_fail_ptest); + tcase_add_test(tc_core, test_xml_pass); + tcase_add_test(tc_core, test_xml_fail); suite_add_tcase(s, tc_core); diff --git a/utils.c b/utils.c index 48c1990..0fb6ff8 100644 --- a/utils.c +++ b/utils.c @@ -306,6 +306,7 @@ run_ptests(struct ptest_list *head, const struct options opts, const char *progn FILE *fp, FILE *fp_stderr) { int rc = 0; + XML *xh; struct ptest_list *p; char stime[GET_STIME_BUF_SIZE]; @@ -314,6 +315,12 @@ run_ptests(struct ptest_list *head, const struct options opts, const char *progn int pipefd_stdout[2]; int pipefd_stderr[2]; + if(opts.xml_filename) { + xh = xml_create(ptest_list_length(head), opts.xml_filename); + if(!xh) + exit(EXIT_FAILURE); + } + do { if ((rc = pipe2(pipefd_stdout, O_NONBLOCK)) == -1) @@ -355,6 +362,9 @@ run_ptests(struct ptest_list *head, const struct options opts, const char *progn fprintf(fp, "ERROR: Exit status is %d\n", status); rc += 1; } + if (opts.xml_filename) + xml_add_case(xh, status, ptest_dir); + fprintf(fp, "END: %s\n", ptest_dir); fprintf(fp, "%s\n", get_stime(stime, GET_STIME_BUF_SIZE)); } @@ -368,5 +378,45 @@ run_ptests(struct ptest_list *head, const struct options opts, const char *progn if (rc == -1) fprintf(fp_stderr, "run_ptests fails: %s", strerror(errno)); + if (opts.xml_filename) + xml_finish(xh); + return rc; } + +FILE * +xml_create(int test_count, char *xml_filename) +{ + FILE *xh; + + if ((xh = fopen(xml_filename, "w"))) { + fprintf(xh, "<?xml version='1.0' encoding='UTF-8'?>\n"); + fprintf(xh, "<testsuite name='ptest' tests='%d'>\n", test_count); + } + else { + fprintf(stderr, "File could not be created. Make sure the path is correct and you have the right permissions."); + return NULL; + } + + return xh; +} + +void +xml_add_case(FILE *xh, int status, const char *ptest_dir) +{ + fprintf(xh, "<testcase classname='%s' name='run-ptest'>\n", ptest_dir); + + if(status != 0){ + fprintf(xh, "<failure type='exit_code'"); + fprintf(xh, " message='run-ptest exited with code: %d'>", status); + fprintf(xh, "</failure>\n"); + } + fprintf(xh, "</testcase>\n"); +} + +void +xml_finish(FILE *xh) +{ + fprintf(xh, "</testsuite>\n"); + fclose(xh); +} diff --git a/utils.h b/utils.h index d7f5268..7a8956a 100644 --- a/utils.h +++ b/utils.h @@ -33,14 +33,20 @@ struct options { char *directory; int list; - int timeout; - char **ptests; + int timeout; + char **ptests; + char * xml_filename; }; +typedef FILE XML; + extern void check_allocation1(void *, size_t, char *, int, int); extern struct ptest_list *get_available_ptests(const char *); extern int print_ptests(struct ptest_list *, FILE *); extern struct ptest_list *filter_ptests(struct ptest_list *, char **, int); extern int run_ptests(struct ptest_list *, const struct options, const char *progname, FILE *, FILE *); +extern XML * xml_create(int test_count, char *filename); +extern void xml_add_case(XML *, int status, const char *ptest_dir); +extern void xml_finish(XML *); #endif -- 2.1.4 ^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [ptest-runner][PATCHv2 2/2] Add xml output 2017-02-01 15:42 ` [ptest-runner][PATCHv2 2/2] Add xml output Pascal Bach @ 2017-04-06 21:12 ` Aníbal Limón 0 siblings, 0 replies; 3+ messages in thread From: Aníbal Limón @ 2017-04-06 21:12 UTC (permalink / raw) To: Pascal Bach, yocto; +Cc: Schuler Christian [-- Attachment #1: Type: text/plain, Size: 8901 bytes --] Hi Pascal, I did some changes to your patch, see comments inline. As i said i plan to integrate for 2.1 version of ptest-runner. See the branch, http://git.yoctoproject.org/cgit/cgit.cgi/ptest-runner2/log/?h=devel Thanks for your contribution, Anibal On 02/01/2017 09:42 AM, Pascal Bach wrote: > The format follow the one defined in the Yocto wiki: > https://wiki.yoctoproject.org/wiki/QA/xUnit_XML_Template > > It is only the minimum required but it can be extended in the future. > > Signed-off-by: Schuler Christian <schuler.christian@siemens.com> > Signed-off-by: Pascal Bach <pascal.bach@siemens.com> > --- > README.md | 1 + > main.c | 13 ++++++++++--- > tests/data/reference.xml | 8 ++++++++ > tests/utils.c | 46 ++++++++++++++++++++++++++++++++++++++++++++ > utils.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ > utils.h | 10 ++++++++-- > 6 files changed, 123 insertions(+), 5 deletions(-) > create mode 100644 tests/data/reference.xml > > diff --git a/README.md b/README.md > index ed7a589..fedab04 100644 > --- a/README.md > +++ b/README.md > @@ -14,6 +14,7 @@ Now the ptest-runner2 support the next features: > - List available ptests. > - Specify the timeout for avoid blocking indefinetly. > - Only run certain ptests. > +- XML-ouput > > Proposed features: > > diff --git a/main.c b/main.c > index 765d688..5f37541 100644 > --- a/main.c > +++ b/main.c > @@ -41,7 +41,7 @@ > static inline void > print_usage(FILE *stream, char *progname) > { > - fprintf(stream, "Usage: %s [-d directory] [-l list] [-t timeout] " > + fprintf(stream, "Usage: %s [-d directory] [-l list] [-t timeout] [-x xml-filename]" > "[-h] [ptest1 ptest2 ...]\n", progname); > } > > @@ -60,12 +60,14 @@ main(int argc, char *argv[]) > struct ptest_list *head, *run; > > struct options opts; > + > opts.directory = strdup(DEFAULT_DIRECTORY); > opts.list = 0; > opts.timeout = DEFAULT_TIMEOUT; > opts.ptests = NULL; > + opts.xml_filename = NULL; > > - while ((opt = getopt(argc, argv, "d:lt:h")) != -1) { > + while ((opt = getopt(argc, argv, "d:ltx:h")) != -1) { > switch (opt) { > case 'd': > free(opts.directory); > @@ -82,6 +84,11 @@ main(int argc, char *argv[]) > print_usage(stdout, argv[0]); > exit(0); > break; > + case 'x': > + free(opts.xml_filename); > + opts.xml_filename = strdup(optarg); > + CHECK_ALLOCATION(opts.xml_filename, 1, 1); > + break; > default: > print_usage(stdout, argv[0]); > exit(1); > @@ -125,7 +132,7 @@ main(int argc, char *argv[]) > run = filter_ptests(head, opts.ptests, ptest_num); > CHECK_ALLOCATION(run, ptest_num, 1); > ptest_list_free_all(head); > - } > + } > > rc = run_ptests(run, opts, argv[0], stdout, stderr); > > diff --git a/tests/data/reference.xml b/tests/data/reference.xml > new file mode 100644 > index 0000000..0d858e1 > --- /dev/null > +++ b/tests/data/reference.xml > @@ -0,0 +1,8 @@ > +<?xml version='1.0' encoding='UTF-8'?> > +<testsuite name='ptest' tests='2'> > +<testcase classname='test1' name='run-ptest'> > +</testcase> > +<testcase classname='test2' name='run-ptest'> > +<failure type='exit_code' message='run-ptest exited with code: 1'></failure> > +</testcase> > +</testsuite> The format is better to use tabs, for denote hierarchy , i changed this part. Example: <?xml version='1.0' encoding='UTF-8'?> <testsuite name='ptest' tests='2'> <testcase classname='test1' name='run-ptest'> </testcase> <testcase classname='test2' name='run-ptest'> <failure type='exit_code' message='run-ptest exited with code: 1'>< /failure> </testcase> </testsuite> > diff --git a/tests/utils.c b/tests/utils.c > index 6b70c2e..f5d3b62 100644 > --- a/tests/utils.c > +++ b/tests/utils.c > @@ -237,6 +237,50 @@ START_TEST(test_run_fail_ptest) > ptest_list_free_all(head); > END_TEST > > +int filecmp(FILE *fp1, FILE *fp2) Style: int filecmp(FILE *fp1, FILE *fp2) > +{ > + char f1, f2; > + while (1) { > + int end = 0; > + if ((f1 = getc(fp1)) == EOF) end++; > + if ((f2 = getc(fp2)) == EOF) end++; > + > + if (end == 2) return 0; > + if (end == 1) return 1; > + if (f1 != f2) return 2; > + } > +} > + > +START_TEST(test_xml_pass) > + > + > + > + XML *xp; > + xp = xml_create(2, "./test.xml"); > + ck_assert(xp != NULL); > + xml_add_case(xp, 0,"test1"); > + xml_add_case(xp, 1,"test2"); > + xml_finish(xp); > + > + FILE *fp, *fr; > + fr = fopen("./tests/data/reference.xml", "r"); > + ck_assert(fr != NULL); > + fp = fopen("./test.xml", "r"); > + ck_assert(fp != NULL); > + > + ck_assert(filecmp(fr, fp) == 0); > + > + fclose(fr); > + fclose(fp); > + unlink("./test.xml"); Removed blanks and change to tabs instead of spaces. > + > +END_TEST > + > +START_TEST(test_xml_fail) > + ck_assert(xml_create(2, "./") == NULL); > + > +END_TEST > + > Suite * > utils_suite() > { > @@ -252,6 +296,8 @@ utils_suite() > tcase_add_test(tc_core, test_run_ptests); > tcase_add_test(tc_core, test_run_timeout_ptest); > tcase_add_test(tc_core, test_run_fail_ptest); > + tcase_add_test(tc_core, test_xml_pass); > + tcase_add_test(tc_core, test_xml_fail); > > suite_add_tcase(s, tc_core); > > diff --git a/utils.c b/utils.c > index 48c1990..0fb6ff8 100644 > --- a/utils.c > +++ b/utils.c > @@ -306,6 +306,7 @@ run_ptests(struct ptest_list *head, const struct options opts, const char *progn > FILE *fp, FILE *fp_stderr) > { > int rc = 0; > + XML *xh; > > struct ptest_list *p; > char stime[GET_STIME_BUF_SIZE]; > @@ -314,6 +315,12 @@ run_ptests(struct ptest_list *head, const struct options opts, const char *progn > int pipefd_stdout[2]; > int pipefd_stderr[2]; > > + if(opts.xml_filename) { > + xh = xml_create(ptest_list_length(head), opts.xml_filename); > + if(!xh) > + exit(EXIT_FAILURE); > + } > + > do > { > if ((rc = pipe2(pipefd_stdout, O_NONBLOCK)) == -1) > @@ -355,6 +362,9 @@ run_ptests(struct ptest_list *head, const struct options opts, const char *progn > fprintf(fp, "ERROR: Exit status is %d\n", status); > rc += 1; > } > + if (opts.xml_filename) > + xml_add_case(xh, status, ptest_dir); > + > fprintf(fp, "END: %s\n", ptest_dir); > fprintf(fp, "%s\n", get_stime(stime, GET_STIME_BUF_SIZE)); > } > @@ -368,5 +378,45 @@ run_ptests(struct ptest_list *head, const struct options opts, const char *progn > if (rc == -1) > fprintf(fp_stderr, "run_ptests fails: %s", strerror(errno)); > > + if (opts.xml_filename) > + xml_finish(xh); > + > return rc; > } > + > +FILE * > +xml_create(int test_count, char *xml_filename) > +{ > + FILE *xh; > + > + if ((xh = fopen(xml_filename, "w"))) { > + fprintf(xh, "<?xml version='1.0' encoding='UTF-8'?>\n"); > + fprintf(xh, "<testsuite name='ptest' tests='%d'>\n", test_count); > + } > + else { > + fprintf(stderr, "File could not be created. Make sure the path is correct and you have the right permissions."); > + return NULL; > + } > + > + return xh; > +} > + > +void > +xml_add_case(FILE *xh, int status, const char *ptest_dir) > +{ > + fprintf(xh, "<testcase classname='%s' name='run-ptest'>\n", ptest_dir); > + > + if(status != 0){ > + fprintf(xh, "<failure type='exit_code'"); > + fprintf(xh, " message='run-ptest exited with code: %d'>", status); > + fprintf(xh, "</failure>\n"); > + } > + fprintf(xh, "</testcase>\n"); > +} > + > +void > +xml_finish(FILE *xh) > +{ > + fprintf(xh, "</testsuite>\n"); > + fclose(xh); > +} > diff --git a/utils.h b/utils.h > index d7f5268..7a8956a 100644 > --- a/utils.h > +++ b/utils.h > @@ -33,14 +33,20 @@ > struct options { > char *directory; > int list; > - int timeout; > - char **ptests; > + int timeout; > + char **ptests; > + char * xml_filename; > }; Changed struct name to ptest_options and style. > > +typedef FILE XML; Removed typedef, i don't like to use typedefs because it obfuscates code and is a simple FILE. Anibal > + > extern void check_allocation1(void *, size_t, char *, int, int); > extern struct ptest_list *get_available_ptests(const char *); > extern int print_ptests(struct ptest_list *, FILE *); > extern struct ptest_list *filter_ptests(struct ptest_list *, char **, int); > extern int run_ptests(struct ptest_list *, const struct options, const char *progname, FILE *, FILE *); > +extern XML * xml_create(int test_count, char *filename); > +extern void xml_add_case(XML *, int status, const char *ptest_dir); > +extern void xml_finish(XML *); > > #endif > [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 836 bytes --] ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2017-04-06 21:08 UTC | newest] Thread overview: 3+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2017-02-01 15:42 [ptest-runner][PATCHv2 1/2] utils, main: pass opts struct to run_ptests Pascal Bach 2017-02-01 15:42 ` [ptest-runner][PATCHv2 2/2] Add xml output Pascal Bach 2017-04-06 21:12 ` Aníbal Limón
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.