Thanks for the patch, could you help potential reviewers to understand what the patch adds and why by improving the commit message?

There's a lot of noise in this patch with unrelated whitespace changes and formatting changes. Please re-send without those changes. Existing coding style should be maintained.

Thanks,

Joshua

On 29/09/17 03:09, Jiwei Sun wrote:
Kinda only makes sense with JUnit test output.

Signed-off-by: Jiwei Sun <[email protected]>
---
  ptest_list.c                         |  16 +--
  ptest_list.h                         |  14 ++-
  tests/data/glibc/ptest/run-pptest    |   3 +
  tests/data/parallel/ptest/run-pptest |   3 +
  tests/ptest_list.c                   |  10 +-
  tests/utils.c                        |  13 ++-
  utils.c                              | 183 +++++++++++++++++++++++++++++++----
  utils.h                              |   2 +-
  8 files changed, 207 insertions(+), 37 deletions(-)
  create mode 100755 tests/data/glibc/ptest/run-pptest
  create mode 100755 tests/data/parallel/ptest/run-pptest

diff --git a/ptest_list.c b/ptest_list.c
index 2e1aa30..8a59383 100644
--- a/ptest_list.c
+++ b/ptest_list.c
@@ -27,8 +27,8 @@
  #include "utils.h"
  #include "ptest_list.h"
-#define VALIDATE_PTR_RINT(ptr) if (ptr == NULL) { errno = EINVAL; return -1; }
-#define VALIDATE_PTR_RNULL(ptr) if (ptr == NULL) { errno = EINVAL; return 
NULL; }
+#define VALIDATE_PTR_RINT(ptr) if (ptr == NULL) { errno = EINVAL; return -1; }
+#define VALIDATE_PTR_RNULL(ptr) if (ptr == NULL) { errno = EINVAL; return 
NULL; }
struct ptest_list *
  ptest_list_alloc()
@@ -98,7 +98,7 @@ ptest_list_search(struct ptest_list *head, char *ptest)
        VALIDATE_PTR_RNULL(ptest);
for (p = head; p != NULL; p = p->next) {
-               if (p->ptest == NULL)
+               if (p->ptest == NULL)
                        continue;
if (strcmp(p->ptest, ptest) == 0) {
@@ -111,9 +111,12 @@ ptest_list_search(struct ptest_list *head, char *ptest)
  }
struct ptest_list *
-ptest_list_add(struct ptest_list *head, char *ptest, char *run_ptest)
+ptest_list_add(struct ptest_list *head,
+              char *ptest,
+              char *run_ptest,
+              int parallel)
  {
-       struct ptest_list *n, *p;
+       struct ptest_list *n, *p;
VALIDATE_PTR_RNULL(head);
        VALIDATE_PTR_RNULL(ptest);
@@ -124,6 +127,7 @@ ptest_list_add(struct ptest_list *head, char *ptest, char 
*run_ptest)
n->ptest = ptest;
        n->run_ptest = run_ptest;
+       n->parallel = parallel;
n->prev = NULL;
        n->next = NULL;
@@ -139,7 +143,7 @@ ptest_list_add(struct ptest_list *head, char *ptest, char 
*run_ptest)
  struct ptest_list *
  ptest_list_remove(struct ptest_list *head, char *ptest, int free)
  {
-       struct ptest_list *p;
+       struct ptest_list *p;
        struct ptest_list *q, *r;
VALIDATE_PTR_RNULL(head);
diff --git a/ptest_list.h b/ptest_list.h
index 8b39485..e627921 100644
--- a/ptest_list.h
+++ b/ptest_list.h
@@ -25,12 +25,19 @@
  #define PTEST_LIST_FREE_CLEAN(x) { ptest_list_free(x); x = NULL; }
  #define PTEST_LIST_FREE_ALL_CLEAN(x) { ptest_list_free_all(x); x = NULL; }
-#define PTEST_LIST_ITERATE_START(head, p) for (p = head->next; p != NULL; p = p->next) {
+#define PTEST_LIST_ITERATE_START(head, p) for (p = head->next; p != NULL; p = 
p->next) {
  #define PTEST_LIST_ITERATE_END }
+struct ptest_entry {
+       char *ptest;
+       char *run_ptest;
+       int parallel;
+};
+
  struct ptest_list {
        char *ptest;
        char *run_ptest;
+       int parallel;
struct ptest_list *next;
        struct ptest_list *prev;
@@ -42,7 +49,10 @@ extern int ptest_list_free_all(struct ptest_list *);
extern int ptest_list_length(struct ptest_list *);
  extern struct ptest_list *ptest_list_search(struct ptest_list *, char *);
-extern struct ptest_list *ptest_list_add(struct ptest_list *, char *, char *);
+extern struct ptest_list *ptest_list_add(struct ptest_list *,
+                                        char *,
+                                        char *,
+                                        int);
  extern struct ptest_list *ptest_list_remove(struct ptest_list *, char *, int);
#endif // _PTEST_RUNNER_LIST_H_
diff --git a/tests/data/glibc/ptest/run-pptest 
b/tests/data/glibc/ptest/run-pptest
new file mode 100755
index 0000000..f7f0316
--- /dev/null
+++ b/tests/data/glibc/ptest/run-pptest
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+echo "glibc"
diff --git a/tests/data/parallel/ptest/run-pptest 
b/tests/data/parallel/ptest/run-pptest
new file mode 100755
index 0000000..23a0fff
--- /dev/null
+++ b/tests/data/parallel/ptest/run-pptest
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+echo "parallel"
diff --git a/tests/ptest_list.c b/tests/ptest_list.c
index 2641620..a02af0e 100644
--- a/tests/ptest_list.c
+++ b/tests/ptest_list.c
@@ -49,7 +49,7 @@ END_TEST
  START_TEST(test_add)
  {
        struct ptest_list *head = ptest_list_alloc();
-       ck_assert(ptest_list_add(head, strdup("perl"), NULL) != NULL);
+       ck_assert(ptest_list_add(head, strdup("perl"), NULL, 0) != NULL);
        ptest_list_free_all(head);
  }
  END_TEST
@@ -64,7 +64,7 @@ START_TEST(test_free_all)
head = ptest_list_alloc();
        for (i = 0; i < ptests_num; i++)
-               ptest_list_add(head, strdup(ptest_names[i]), NULL);
+               ptest_list_add(head, strdup(ptest_names[i]), NULL, 0);
ptest_list_free_all(head);
  }
@@ -81,7 +81,7 @@ START_TEST(test_length)
head = ptest_list_alloc();
        for (i = 0; i < ptests_num; i++)
-               ptest_list_add(head, strdup(ptest_names[i]), NULL);
+               ptest_list_add(head, strdup(ptest_names[i]), NULL, 0);
ck_assert_int_eq(ptest_list_length(head), ptests_num);
        ptest_list_free_all(head);
@@ -100,7 +100,7 @@ START_TEST(test_search)
        head = ptest_list_alloc();
        for (i = 0; i < ptests_num; i++) {
                ptest = strdup(ptest_names[i]);
-               ptest_list_add(head, ptest, NULL);
+               ptest_list_add(head, ptest, NULL, 0);
        }
for (i = ptests_num - 1; i >= 0; i--)
@@ -119,7 +119,7 @@ START_TEST(test_remove)
for (i = 0; i < ptests_num; i++) {
                ptest = strdup(ptest_names[i]);
-               ptest_list_add(head, ptest, NULL);
+               ptest_list_add(head, ptest, NULL, 0);
        }
/* Remove node free'ing */
diff --git a/tests/utils.c b/tests/utils.c
index ecf3e8a..9b1f442 100644
--- a/tests/utils.c
+++ b/tests/utils.c
@@ -40,11 +40,13 @@ static char *ptests_found[] = {
        "fail",
        "gcc",
        "glibc",
+       "glibc",
        "hang",
+       "parallel",
        "python",
        NULL
  };
-static int ptests_found_length = 6;
+static int ptests_found_length = 8;
  static char *ptests_not_found[] = {
        "busybox",
        "perl",
@@ -254,10 +256,15 @@ filecmp(FILE *fp1, FILE *fp2)
START_TEST(test_xml_pass)
        FILE *xp;
+        struct ptest_entry entry;
+
        xp = xml_create(2, "./test.xml");
        ck_assert(xp != NULL);
-       xml_add_case(xp, 0,"test1");
-       xml_add_case(xp, 1,"test2");
+        entry.ptest = "test1";
+        entry.run_ptest = "run-ptest";
+       xml_add_case(xp, 0, &entry);
+        entry.ptest = "test2";
+        xml_add_case(xp, 1, &entry);
        xml_finish(xp);
FILE *fp, *fr;
diff --git a/utils.c b/utils.c
index a07faec..056d7b7 100644
--- a/utils.c
+++ b/utils.c
@@ -42,7 +42,7 @@
#define GET_STIME_BUF_SIZE 1024
  #define WAIT_CHILD_POLL_TIMEOUT_MS 200
-#define WAIT_CHILD_BUF_MAX_SIZE 1024
+#define WAIT_CHILD_BUF_MAX_SIZE 4096
static inline char *
  get_stime(char *stime, size_t size)
@@ -108,7 +108,6 @@ get_available_ptests(const char *dir)
                fail = 0;
                for (i = 0; i < n; i++) {
                        char *run_ptest;
-
                        char *d_name = strdup(namelist[i]->d_name);
                        CHECK_ALLOCATION(d_name, sizeof(namelist[i]->d_name), 
0);
                        if (d_name == NULL) {
@@ -124,7 +123,7 @@ get_available_ptests(const char *dir)
                        }
if (asprintf(&run_ptest, "%s/%s/ptest/run-ptest",
-                           dir, d_name) == -1)  {
+                                    dir, d_name) == -1) {
                                fail = 1;
                                saved_errno = errno;
                                free(d_name);
@@ -133,18 +132,52 @@ get_available_ptests(const char *dir)
if (stat(run_ptest, &st_buf) == -1) {
                                free(run_ptest);
+                               goto parallel;
+                       }
+
+                       if (!S_ISREG(st_buf.st_mode)) {
+                               free(run_ptest);
+                               goto parallel;
+                       }
+
+                       struct ptest_list *p = ptest_list_add(head,
+                                                             d_name,
+                                                             run_ptest,
+                                                             0);
+
+                       CHECK_ALLOCATION(p, sizeof(struct ptest_list *), 0);
+                       if (p == NULL) {
+                               fail = 1;
+                               saved_errno = errno;
+                               free(run_ptest);
+                               free(d_name);
+                               break;
+                       }
+
+               parallel:
+                       if (asprintf(&run_ptest, "%s/%s/ptest/run-pptest",
+                                    dir, d_name) == -1) {
+                               fail = 1;
+                               saved_errno = errno;
                                free(d_name);
+                               break;
+                       }
+
+                       if (stat(run_ptest, &st_buf) == -1) {
+                               free(run_ptest);
                                continue;
                        }
if (!S_ISREG(st_buf.st_mode)) {
                                free(run_ptest);
-                               free(d_name);
                                continue;
                        }
- struct ptest_list *p = ptest_list_add(head,
-                               d_name, run_ptest);
+                       p = ptest_list_add(head,
+                                          strdup(d_name),
+                                          run_ptest,
+                                          1);
+
                        CHECK_ALLOCATION(p, sizeof(struct ptest_list *), 0);
                        if (p == NULL) {
                                fail = 1;
@@ -162,7 +195,7 @@ get_available_ptests(const char *dir)
                if (fail) {
                        PTEST_LIST_FREE_ALL_CLEAN(head);
                        errno = saved_errno;
-                       break;
+                       return NULL;
                }
        } while (0);
@@ -220,7 +253,10 @@ filter_ptests(struct ptest_list *head, char **ptests, int ptest_num)
                                break;
                        }
- if (ptest_list_add(head_new, ptest, run_ptest) == NULL) {
+                       if (ptest_list_add(head_new,
+                                          ptest,
+                                          run_ptest,
+                                          n->parallel) == NULL) {
                                saved_errno = errno;
                                fail = 1;
                                break;
@@ -288,7 +324,7 @@ wait_child(const char *ptest_dir, const char *run_ptest, 
pid_t pid,
                                        fwrite(buf, n, 1, fps[1]);
                        }
- sentinel = time(NULL);
+               sentinel = time(NULL);
                } else if (timeout >= 0 && ((time(NULL) - sentinel) > timeout)) 
{
                        timeouted = 1;
                        kill(pid, SIGKILL);
@@ -303,11 +339,11 @@ wait_child(const char *ptest_dir, const char *run_ptest, 
pid_t pid,
                if (timeouted)
                        fprintf(fps[0], "TIMEOUT: %s ", ptest_dir);
- if(WIFEXITED(status)) {
+               if(WIFEXITED(status) && pid > 0) {
                        fprintf(fps[0], "\nERROR: Exit status is %d\n", 
WEXITSTATUS(status));
                        return WEXITSTATUS(status);
                }
-               else if(WIFSIGNALED(status)) {
+               else if(WIFSIGNALED(status) && pid > 0) {
                        fprintf(fps[0], " Killed by signal\n");
                        return 127;
                }
@@ -328,7 +364,7 @@ run_ptests(struct ptest_list *head, const struct 
ptest_options opts,
        struct ptest_list *p;
        char stime[GET_STIME_BUF_SIZE];
- pid_t child;
+       pid_t child, pid;
        int pipefd_stdout[2];
        int pipefd_stderr[2];
@@ -336,6 +372,7 @@ run_ptests(struct ptest_list *head, const struct ptest_options opts,
                xh = xml_create(ptest_list_length(head), opts.xml_filename);
                if (!xh)
                        exit(EXIT_FAILURE);
+               fflush(xh);
        }
do
@@ -349,9 +386,90 @@ run_ptests(struct ptest_list *head, const struct 
ptest_options opts,
                        break;
                }
+ fprintf(fp, "START PARALLEL: %s\n", progname);
+               PTEST_LIST_ITERATE_START(head, p);
+                       char *ptest_dir;
+                       int master;
+
+                       if (!p->parallel)
+                               continue;
+
+                       master = fork();
+                       if (master)
+                               continue;
+
+                       ptest_dir = strdup(p->run_ptest);
+                       if (ptest_dir == NULL) {
+                               rc = -1;
+                               break;
+                       }
+                       dirname(ptest_dir);
+
+                       child = fork();
+                       if (child == -1) {
+                               fprintf(fp, "ERROR: Fork %s\n", 
strerror(errno));
+                               rc = -1;
+                               break;
+                       } else if (child == 0) {
+                               run_child(p->run_ptest, pipefd_stdout[1], 
pipefd_stderr[1]);
+                       } else {
+                               int status;
+                               int fds[2]; fds[0] = pipefd_stdout[0]; fds[1] = 
pipefd_stderr[0];
+                               FILE *fps[2]; fps[0] = fp; fps[1] = fp_stderr;
+
+//                             fprintf(fp, "%s\n", get_stime(stime, 
GET_STIME_BUF_SIZE));
+                               fprintf(fp, "BEGIN: %s\n", ptest_dir);
+
+                               status = wait_child(ptest_dir, p->run_ptest, 
child,
+                                               opts.timeout, fds, fps);
+                               if (status)
+                                       rc += 1;
+
+                               if (opts.xml_filename)
+                                       xml_add_case(xh,
+                                                    status,
+                                                    (struct ptest_entry *)p);
+
+//                             fprintf(fp, "END: %s\n", ptest_dir);
+//                             fprintf(fp, "%s\n", get_stime(stime, 
GET_STIME_BUF_SIZE));
+                               /* Let non-master gracefully terminate */
+                               exit(0);
+                       }
+               PTEST_LIST_ITERATE_END;
+
+               /* Reap all children before continuing */
+               while (1) {
+                       int status;
+                       pid = waitpid((pid_t)(-1), &status, WNOHANG);
+
+                       /* Child reaped */
+                       if (pid > 0) {
+                               if (WIFEXITED(status)) {
+                                       if (WEXITSTATUS(status) == 0)
+                                               continue;
+                               }
+                               fprintf(fp, "One child failed to do its job 
pid:%u", pid);
+                               exit(-1);
+                       }
+
+                       /* Still children alive */
+                       if (pid == 0) {
+                               usleep(100000); /* 100ms */
+                               continue;
+                       }
+
+                       /* No more children to reap */
+                       if (pid < 0)
+                               break;
+               }
+
                fprintf(fp, "START: %s\n", progname);
                PTEST_LIST_ITERATE_START(head, p);
-                       char *ptest_dir = strdup(p->run_ptest);
+                       char *ptest_dir;
+                       if (p->parallel)
+                               continue;
+
+                       ptest_dir = strdup(p->run_ptest);
                        if (ptest_dir == NULL) {
                                rc = -1;
                                break;
@@ -379,7 +497,9 @@ run_ptests(struct ptest_list *head, const struct 
ptest_options opts,
                                        rc += 1;
if (opts.xml_filename)
-                                       xml_add_case(xh, status, ptest_dir);
+                                       xml_add_case(xh,
+                                                    status,
+                                                    (struct ptest_entry *)p);
fprintf(fp, "END: %s\n", ptest_dir);
                                fprintf(fp, "%s\n", get_stime(stime, 
GET_STIME_BUF_SIZE));
@@ -418,17 +538,40 @@ xml_create(int test_count, char *xml_filename)
  }
void
-xml_add_case(FILE *xh, int status, const char *ptest_dir)
+xml_add_case(FILE *xh, int status, struct ptest_entry *ptest)
  {
-       fprintf(xh, "\t<testcase classname='%s' name='run-ptest'>\n", 
ptest_dir);
+       struct flock lock;
+       int fd;
+       char *bname;
+ fd = fileno(xh);
+       memset (&lock, 0, sizeof(lock));
+       lock.l_type = F_WRLCK;
+       fcntl (fd, F_SETLKW, &lock);
+       bname = strdup(ptest->run_ptest);
+
+       /* fprintf should guarantee atomicity for fprintfs within the same 
process */
        if (status != 0) {
-               fprintf(xh, "\t\t<failure type='exit_code'");
-               fprintf(xh, " message='run-ptest exited with code: %d'>", 
status);
-               fprintf(xh, "</failure>\n");
+               fprintf(xh, "\t<testcase classname='%s' name='%s'>\n" \
+                       "\t\t<failure type='exit_code'" \
+                       " message='run-ptest exited with code: %d'>" \
+                       "</failure>\n" \
+                       "\t</testcase>\n",
+                       ptest->ptest,
+                       basename(bname),
+                       status);
+       }
+       else {
+               fprintf(xh, "\t<testcase classname='%s' name='%s'>\n" \
+                       "\t</testcase>\n",
+                       ptest->ptest,
+                       basename(bname));
        }
- fprintf(xh, "\t</testcase>\n");
+       fflush(xh);
+       lock.l_type = F_UNLCK;
+       fcntl (fd, F_SETLKW, &lock);
+       free(bname);
  }
void
diff --git a/utils.h b/utils.h
index 8fa20a8..d0ef735 100644
--- a/utils.h
+++ b/utils.h
@@ -47,7 +47,7 @@ extern int run_ptests(struct ptest_list *, const struct 
ptest_options,
                const char *, FILE *, FILE *);
extern FILE *xml_create(int, char *);
-extern void xml_add_case(FILE *, int, const char *);
+extern void xml_add_case(FILE *, int, struct ptest_entry *);
  extern void xml_finish(FILE *);
#endif

--
_______________________________________________
yocto mailing list
[email protected]
https://lists.yoctoproject.org/listinfo/yocto

Reply via email to