All of lore.kernel.org
 help / color / mirror / Atom feed
From: Pascal Bach <pascal.bach@siemens.com>
To: yocto@yoctoproject.org
Cc: Schuler Christian <schuler.christian@siemens.com>
Subject: [ptest-runner][PATCHv2 2/2] Add xml output
Date: Wed,  1 Feb 2017 16:42:41 +0100	[thread overview]
Message-ID: <1485963761-25773-2-git-send-email-pascal.bach@siemens.com> (raw)
In-Reply-To: <1485963761-25773-1-git-send-email-pascal.bach@siemens.com>

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



  reply	other threads:[~2017-02-01 15:42 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
2017-04-06 21:12   ` [ptest-runner][PATCHv2 2/2] Add xml output Aníbal Limón

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1485963761-25773-2-git-send-email-pascal.bach@siemens.com \
    --to=pascal.bach@siemens.com \
    --cc=schuler.christian@siemens.com \
    --cc=yocto@yoctoproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.