Re: [PATCH v2 1/3] testsuite: split out function to compare outputs exactly

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Jan 4, 2019 at 8:28 AM Yauheni Kaliuta
<yauheni.kaliuta@xxxxxxxxxx> wrote:
>
> Hi, Lucas!
>
> Just in case, ACK.

pushed, thanks.

Lucas De Marchi

>
> >>>>> On Thu,  3 Jan 2019 13:07:44 -0800, Lucas De Marchi  wrote:
>
>  > Move functionality to compare the exact output to a separate function
>  > and allocate one buffer per output/match pair. This will allow us to
>  > extend this to allow other types of comparisons. Since now we are using
>  > heap-allocated buffer, keep the buffer allocation to the caller, so we
>  > don't have to allocate and free it on every invocation. It also avoids
>  > the different comparison functions to have to deal with it.
>  > ---
>  >  testsuite/testsuite.c | 124 ++++++++++++++++++++++++------------------
>  >  1 file changed, 70 insertions(+), 54 deletions(-)
>
>  > diff --git a/testsuite/testsuite.c b/testsuite/testsuite.c
>  > index 8512b56..508bbd3 100644
>  > --- a/testsuite/testsuite.c
>  > +++ b/testsuite/testsuite.c
>  > @@ -290,13 +290,64 @@ static int check_activity(int fd, bool activity,  const char *path,
>  >      return -1;
>  >  }
>
>  > -static inline bool test_run_parent_check_outputs(const struct test *t,
>  > -                    int fdout, int fderr, int fdmonitor, pid_t child)
>  > +#define BUFSZ 4096
>  > +struct buffer {
>  > +    char buf[BUFSZ];
>  > +};
>  > +
>  > +/* read fd and fd_match, checking they match exactly */
>  > +static bool cmpbuf_exact(const struct test *t, const char *prefix,
>  > +                     int fd, int fd_match, struct buffer *buf,
>  > +                     struct buffer *buf_match)
>  > +{
>  > +    int r, rmatch, done = 0;
>  > +
>  > +    r = read(fd, buf->buf, sizeof(buf->buf) - 1);
>  > +    if (r <= 0)
>  > +            /* try again later */
>  > +            return true;
>  > +
>  > +    /* read as much data from fd_match as we read from fd */
>  > +    for (;;) {
>  > +            rmatch = read(fd_match, buf_match->buf + done, r - done);
>  > +            if (rmatch == 0)
>  > +                    break;
>  > +
>  > +            if (rmatch < 0) {
>  > +                    if (errno == EINTR)
>  > +                            continue;
>  > +                    ERR("could not read match fd %d\n", fd_match);
>  > +                    return false;
>  > +            }
>  > +
>  > +            done += rmatch;
>  > +    }
>  > +
>  > +    buf->buf[r] = '\0';
>  > +    buf_match->buf[r] = '\0';
>  > +
>  > +    if (t->print_outputs)
>  > +            printf("%s: %s\n", prefix, buf->buf);
>  > +
>  > +    if (!streq(buf->buf, buf_match->buf)) {
>  > +            ERR("Outputs do not match on %s:\n", prefix);
>  > +            ERR("correct:\n%s\n", buf_match->buf);
>  > +            ERR("wrong:\n%s\n", buf->buf);
>  > +            return false;
>  > +    }
>  > +
>  > +    return true;
>  > +}
>  > +
>  > +static bool test_run_parent_check_outputs(const struct test *t,
>  > +                                      int fdout, int fderr, int fdmonitor,
>  > +                                      pid_t child)
>  >  {
>  >      struct epoll_event ep_outpipe, ep_errpipe, ep_monitor;
>  >      int err, fd_ep, fd_matchout = -1, fd_matcherr = -1;
>  >      bool fd_activityout = false, fd_activityerr = false;
>  >      unsigned long long end_usec, start_usec;
>  > +    _cleanup_free_ struct buffer *buf_out = NULL, *buf_err = NULL;
>
>  >      fd_ep = epoll_create1(EPOLL_CLOEXEC);
>  >      if (fd_ep < 0) {
>  > @@ -320,6 +371,7 @@ static inline bool test_run_parent_check_outputs(const struct test *t,
>  >                      ERR("could not add fd to epoll: %m\n");
>  >                      goto out;
>  >              }
>  > +            buf_out = calloc(2, sizeof(*buf_out));
>  >      } else
>  >              fdout = -1;
>
>  > @@ -340,6 +392,7 @@ static inline bool test_run_parent_check_outputs(const struct test *t,
>  >                      ERR("could not add fd to epoll: %m\n");
>  >                      goto out;
>  >              }
>  > +            buf_err = calloc(2, sizeof(*buf_err));
>  >      } else
>  >              fderr = -1;
>
>  > @@ -374,76 +427,39 @@ static inline bool test_run_parent_check_outputs(const struct test *t,
>  >              }
>
>  >              for (i = 0;  i < fdcount; i++) {
>  > -                    int *fd = ev[i].data.ptr;
>  > +                    int fd = *(int *)ev[i].data.ptr;
>
>  >                      if (ev[i].events & EPOLLIN) {
>  > -                            ssize_t r, done = 0;
>  > -                            char buf[4096];
>  > -                            char bufmatch[4096];
>  >                              int fd_match;
>  > +                            struct buffer *buf, *buf_match;
>  > +                            const char *prefix;
>
>  > -                            /*
>  > -                             * compare the output from child with the one
>  > -                             * saved as correct
>  > -                             */
>  > -
>  > -                            r = read(*fd, buf, sizeof(buf) - 1);
>  > -                            if (r <= 0)
>  > -                                    continue;
>  > -
>  > -                            if (*fd == fdout) {
>  > +                            if (fd == fdout) {
>  >                                      fd_match = fd_matchout;
>  > +                                    buf = buf_out;
>  >                                      fd_activityout = true;
>  > -                            } else if (*fd == fderr) {
>  > +                                    prefix = "STDOUT";
>  > +                            } else if (fd == fderr) {
>  >                                      fd_match = fd_matcherr;
>  > +                                    buf = buf_err;
>  >                                      fd_activityerr = true;
>  > +                                    prefix = "STDERR";
>  >                              } else {
>  >                                      ERR("Unexpected activity on monitor pipe\n");
>  >                                      err = -EINVAL;
>  >                                      goto out;
>  >                              }
>
>  > -                            for (;;) {
>  > -                                    int rmatch = read(fd_match,
>  > -                                            bufmatch + done, r - done);
>  > -                                    if (rmatch == 0)
>  > -                                            break;
>  > -
>  > -                                    if (rmatch < 0) {
>  > -                                            if (errno == EINTR)
>  > -                                                    continue;
>  > -                                            err = -errno;
>  > -                                            ERR("could not read match fd %d\n",
>  > -                                                            fd_match);
>  > -                                            goto out;
>  > -                                    }
>  > -
>  > -                                    done += rmatch;
>  > -                            }
>  > +                            buf_match = buf + 1;
>
>  > -                            buf[r] = '\0';
>  > -                            bufmatch[r] = '\0';
>  > -
>  > -                            if (t->print_outputs)
>  > -                                    printf("%s: %s\n",
>  > -                                           fd_match == fd_matchout ? "STDOUT:" : "STDERR:",
>  > -                                           buf);
>  > -
>  > -                            if (!streq(buf, bufmatch)) {
>  > -                                    ERR("Outputs do not match on %s:\n",
>  > -                                            fd_match == fd_matchout ? "STDOUT" : "STDERR");
>  > -                                    ERR("correct:\n%s\n", bufmatch);
>  > -                                    ERR("wrong:\n%s\n", buf);
>  > -                                    err = -1;
>  > +                            if (!cmpbuf_exact(t, prefix,  fd, fd_match,
>  > +                                              buf, buf_match))
>  >                                      goto out;
>  > -                            }
>  >                      } else if (ev[i].events & EPOLLHUP) {
>  > -                            if (epoll_ctl(fd_ep, EPOLL_CTL_DEL,
>  > -                                                    *fd, NULL) < 0) {
>  > -                                    ERR("could not remove fd %d from epoll: %m\n",
>  > -                                                                    *fd);
>  > +                            if (epoll_ctl(fd_ep, EPOLL_CTL_DEL, fd, NULL) < 0) {
>  > +                                    ERR("could not remove fd %d from epoll: %m\n", fd);
>  >                              }
>  > -                            *fd = -1;
>  > +                            *(int *)ev[i].data.ptr = -1;
>  >                      }
>  >              }
>  >      }
>  > --
>  > 2.20.0
>
>
> --
> WBR,
> Yauheni Kaliuta



-- 
Lucas De Marchi



[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux