Hi Mike,

On Thu, 2009-07-09 at 03:03 -0400, Mike Frysinger wrote:
> the perceived problem: many many tests duplicate errno display and
> they do so 
> inconsistently.  many times the display is crappy and a lot less
> helpful than 
> it could & should be.  a test should merely have to say "include the
> errno in 
> the test output" so it can focus on its own details.  much like the
> multitude 
> of C library functions out there like perror() or printf's %m.
> 
> the proposed fix: extend the first argument to (1) take a define for
> the test 
> result and (2) also accept optional bit fields to further manipulate
> the 
> output.  the advantage here is we dont have to add a whole lot of
> helper 
> functions to complement the existing ones.  i.e. a new tst_resmp()
> that would 
> behave like tst_resm() but also append the errno output.
> 

I like this idea. Very few comments:

     1. The new patch does not show the implementation of tst_resmp(), 
     2. If there are changes on this regard, the corresponding
        information should be updated in ltp/doc/man3/tst_res.3, 
     3. The new usage of tst_resmp() also should be communicated to
        users, probably through ltp/README,

Regards--
Subrata

> at the moment, the T* defines in test.h are set up like a bit field.
> this is 
> silly because no where are these values treated like bits -- they're
> always 
> checked by their value.  so the first thing is to convert them to a
> linear 
> number map so we can stake out the lower 4 bits for the result.  this
> frees up 
> higher bit values.
> 
> then two new output modifiers are added -- TERRNO and TTERRNO.  the
> former 
> appends errno output using the "errno" value while the latter uses 
> "TEST_ERRNO".  this allows us to convert both types of testing
> methods.  the 
> output too is much more useful for people who are actually reviewing
> testing 
> errors:
> ....: errno=ETXTBSY(26): Text file busy
> the advantage of having all three is that you dont have to spend time
> looking 
> up the value you actually care about, and makes coordinating things
> easier 
> (like strace output and the test source code).
> 
> attached is the patch to do this implementation as well as an example
> of 
> converting mmap09 to the new interface
> -mike
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> differences
> between files
> attachment
> (ltp-ttype-masks.patch)
> 
> 
> --- include/test.h
> +++ include/test.h
> @@ -44,13 +44,19 @@
>  
>  #include "compiler.h"
>  
> -#define TPASS    0    /* Test passed flag */
> -#define TFAIL    1    /* Test failed flag */
> -#define TBROK    2    /* Test broken flag */
> -#define TWARN    4    /* Test warning flag */
> -#define TRETR    8    /* Test retire flag */
> -#define TINFO    16   /* Test information flag */
> -#define TCONF    32   /* Test not appropriate for configuration flag
> */
> +/* Use low 4 bits to encode test type */
> +#define TTYPE_MASK 0xf
> +#define TPASS      0    /* Test passed flag */
> +#define TFAIL      1    /* Test failed flag */
> +#define TBROK      2    /* Test broken flag */
> +#define TWARN      3    /* Test warning flag */
> +#define TRETR      4    /* Test retire flag */
> +#define TINFO      5    /* Test information flag */
> +#define TCONF      6    /* Test not appropriate for configuration
> flag */
> +#define TTYPE_RESULT(ttype) ((ttype) & TTYPE_MASK)
> +
> +#define TERRNO     0x100   /* Append errno information to output */
> +#define TTERRNO    0x200   /* Append TEST_ERRNO information to output
> */
>  
>  /*
>   * To determine if you are on a Umk or Unicos system,
> @@ -179,6 +185,7 @@
>  /*
>   * Functions from lib/tst_res.c
>   */
> +const char *strttype(int ttype);
>  void tst_res(int ttype, char *fname, char *arg_fmt, ...);
>  void tst_resm(int ttype, char *arg_fmt, ...);
>  void tst_brk(int ttype, char *fname, void (*func)(void), char
> *arg_fmt, ...);
> --- lib/tst_res.c
> +++ lib/tst_res.c
> @@ -115,6 +115,7 @@
>  #include <stdarg.h>
>  #include <unistd.h>
>  #include "test.h"
> +#include "usctest.h"
>  
>  #define VERBOSE      1     /* flag values for the T_mode variable */
>  #define CONDENSE     2
> @@ -206,6 +207,80 @@ extern int  TST_TOTAL;  /* Total number 
>   */
>  char *TESTDIR = NULL;
>  
> +struct pair {
> +       const char *name;
> +       int val;
> +};
> +#define PAIR(def) [def] = { .name = #def, .val = def, },
> +const char *pair_lookup(struct pair *pair, int pair_size, int idx)
> +{
> +       if (idx < 0 || idx >= pair_size || pair[idx].name == NULL)
> +               return "???";
> +       return pair[idx].name;
> +}
> +#define pair_lookup(pair, idx) pair_lookup(pair, ARRAY_SIZE(pair),
> idx)
> +
> +/*
> + * strttype() - convert a type result to the human readable string
> + */
> +const char *strttype(int ttype)
> +{
> +       struct pair ttype_pairs[] = {
> +               PAIR(TPASS)
> +               PAIR(TFAIL)
> +               PAIR(TBROK)
> +               PAIR(TRETR)
> +               PAIR(TCONF)
> +               PAIR(TWARN)
> +               PAIR(TINFO)
> +       };
> +       return pair_lookup(ttype_pairs, TTYPE_RESULT(ttype));
> +}
> +
> +/*
> + * strerrnodef() - convert an errno value to its C define
> + */
> +static const char *strerrnodef(int err)
> +{
> +       struct pair errno_pairs[] = {
> +               PAIR(EPERM)
> +               PAIR(ENOENT)
> +               PAIR(ESRCH)
> +               PAIR(EINTR)
> +               PAIR(EIO)
> +               PAIR(ENXIO)
> +               PAIR(E2BIG)
> +               PAIR(ENOEXEC)
> +               PAIR(EBADF)
> +               PAIR(ECHILD)
> +               PAIR(EAGAIN)
> +               PAIR(ENOMEM)
> +               PAIR(EACCES)
> +               PAIR(EFAULT)
> +               PAIR(ENOTBLK)
> +               PAIR(EBUSY)
> +               PAIR(EEXIST)
> +               PAIR(EXDEV)
> +               PAIR(ENODEV)
> +               PAIR(ENOTDIR)
> +               PAIR(EISDIR)
> +               PAIR(EINVAL)
> +               PAIR(ENFILE)
> +               PAIR(EMFILE)
> +               PAIR(ENOTTY)
> +               PAIR(ETXTBSY)
> +               PAIR(EFBIG)
> +               PAIR(ENOSPC)
> +               PAIR(ESPIPE)
> +               PAIR(EROFS)
> +               PAIR(EMLINK)
> +               PAIR(EPIPE)
> +               PAIR(EDOM)
> +               PAIR(ERANGE)
> +       };
> +       return pair_lookup(errno_pairs, err);
> +}
> +
>  /*
>   * tst_res() - Main result reporting function.  Handle test
> information
>   *             appropriately depending on output display mode.  Call
> @@ -217,6 +292,7 @@ void tst_res(int ttype, char *fname, cha
>  {
>         int  i;
>         char tmesg[USERMESG];
> +       int ttype_result = TTYPE_RESULT(ttype);
>  
>  #if DEBUG
>         printf("IN tst_res; Tst_count = %d; Tst_range = %d\n",
> @@ -229,7 +305,7 @@ void tst_res(int ttype, char *fname, cha
>          * Save the test result type by ORing ttype into the current
> exit
>          * value (used by tst_exit()).
>          */
> -       T_exitval |= ttype;
> +       T_exitval |= ttype_result;
>  
>         /*
>          * Unless T_out has already been set by tst_environ(), make
> tst_res()
> @@ -257,7 +333,7 @@ void tst_res(int ttype, char *fname, cha
>          * Set the test case number and print the results, depending
> on the
>          * display type.
>          */
> -       if (ttype == TWARN || ttype == TINFO) {
> +       if (ttype_result == TWARN || ttype_result == TINFO) {
>                 if (Tst_range > 1)
>                         tst_print(TCID, 0, 1, TWARN,
>                                   "tst_res(): Range not valid for
> TINFO or TWARN types");
> @@ -303,6 +379,7 @@ void tst_res(int ttype, char *fname, cha
>  static void tst_condense(int tnum, int ttype, char *tmesg)
>  {
>         char *file;
> +       int ttype_result = TTYPE_RESULT(ttype);
>  
>  #if DEBUG
>         printf("IN tst_condense: tcid = %s, tnum = %d, ttype = %d,
> tmesg = %s\n",
> @@ -314,7 +391,7 @@ static void tst_condense(int tnum, int t
>          * If this result is the same as the previous result, return.
>          */
>         if (Buffered == TRUE) {
> -               if (strcmp(Last_tcid, TCID) == 0 && Last_type == ttype
> &&
> +               if (strcmp(Last_tcid, TCID) == 0 && Last_type ==
> ttype_result &&
>                     strcmp(Last_mesg, tmesg) == 0 && File == NULL )
>                         return;
>  
> @@ -343,7 +420,7 @@ static void tst_condense(int tnum, int t
>                 Last_tcid = (char *)malloc(strlen(TCID) + 1);
>                 strcpy(Last_tcid, TCID);
>                 Last_num = tnum;
> -               Last_type = ttype;
> +               Last_type = ttype_result;
>                 Last_mesg = (char *)malloc(strlen(tmesg) + 1);
>                 strcpy(Last_mesg, tmesg);
>                 Buffered = TRUE;
> @@ -381,7 +458,8 @@ void tst_flush(void)
>   */
>  static void tst_print(char *tcid, int tnum, int trange, int ttype,
> char *tmesg)
>  {
> -       char type[5];
> +       const char *type;
> +       int ttype_result = TTYPE_RESULT(ttype);
>  
>  #if DEBUG
>         printf("IN tst_print: tnum = %d, trange = %d, ttype = %d,
> tmesg = %s\n",
> @@ -395,7 +473,7 @@ static void tst_print(char *tcid, int tn
>          * also done here to catch internal warnings.  For internal
> warnings,
>          * tst_print() is called directly with a case of TWARN.
>          */
> -       T_exitval |= ttype;
> +       T_exitval |= ttype_result;
>  
>         /*
>          * If output mode is DISCARD, or if the output mode is NOPASS
> and this
> @@ -404,53 +482,33 @@ static void tst_print(char *tcid, int tn
>          * tst_res(), since occasionally we get to this point without
> going
>          * through tst_res() (e.g. internal TWARN messages).
>          */
> -       if (T_mode == DISCARD || (T_mode == NOPASS && ttype != TFAIL
> &&
> -           ttype != TBROK && ttype != TWARN))
> +       if (T_mode == DISCARD || (T_mode == NOPASS && ttype_result !=
> TFAIL &&
> +           ttype_result != TBROK && ttype_result != TWARN))
>                 return;
>  
>         /*
> -        * Fill in the type string according to ttype.
> -        */
> -       switch (ttype) {
> -               case TPASS:
> -                       strcpy(type, "PASS");
> -               break;
> -               case TFAIL:
> -                       strcpy(type, "FAIL");
> -               break;
> -               case TBROK:
> -                       strcpy(type, "BROK");
> -               break;
> -               case TRETR:
> -                       strcpy(type, "RETR");
> -               break;
> -               case TCONF:
> -                       strcpy(type, "CONF");
> -               break;
> -               case TWARN:
> -                       strcpy(type, "WARN");
> -               break;
> -               case TINFO:
> -                       strcpy(type, "INFO");
> -               break;
> -               default:
> -                       strcpy(type, "????");
> -               break;
> -       }
> -
> -       /*
>          * Build the result line and print it.
>          */
> +       type = strttype(ttype);
>         if (T_mode == VERBOSE) {
> -               fprintf(T_out, "%-8s %4d  %s  :  %s\n", tcid, tnum,
> type, tmesg);
> +               fprintf(T_out, "%-8s %4d  %s  :  %s", tcid, tnum,
> type, tmesg);
>         } else {
>                 if (trange > 1)
> -                       fprintf(T_out, "%-8s %4d-%-4d  %s  :  %s\n",
> +                       fprintf(T_out, "%-8s %4d-%-4d  %s  :  %s",
>                                 tcid, tnum, tnum + trange - 1, type,
> tmesg);
>                 else
> -                       fprintf(T_out, "%-8s %4d       %s  :  %s\n",
> +                       fprintf(T_out, "%-8s %4d       %s  :  %s",
>                                 tcid, tnum, type, tmesg);
>         }
> +       if (ttype & TERRNO) {
> +               int err = errno; /* avoid unintended side effects */
> +               fprintf(T_out, ": errno=%s(%i): %s", strerrnodef(err),
> +                       err, strerror(err));
> +       }
> +       if (ttype & TTERRNO)
> +               fprintf(T_out, ": TEST_ERRNO=%s(%i): %s",
> strerrnodef(TEST_ERRNO),
> +                       (int)TEST_ERRNO, strerror(TEST_ERRNO));
> +       fprintf(T_out, "\n");
>  
>         /*
>          * If tst_res() was called with a file, append file contents
> to the
> @@ -559,6 +617,7 @@ int tst_environ(void)
>  void tst_brk(int ttype, char *fname, void (*func)(void), char
> *arg_fmt, ...)
>  {
>         char tmesg[USERMESG];
> +       int ttype_result = TTYPE_RESULT(ttype);
>  
>  #if DEBUG
>         printf("IN tst_brk\n"); fflush(stdout);
> @@ -570,10 +629,10 @@ void tst_brk(int ttype, char *fname, voi
>         /*
>          * Only FAIL, BROK, CONF, and RETR are supported by tst_brk().
>          */
> -       if (ttype != TFAIL && ttype != TBROK && ttype != TCONF &&
> -           ttype != TRETR ) {
> +       if (ttype_result != TFAIL && ttype_result != TBROK &&
> +           ttype_result != TCONF && ttype_result != TRETR) {
>                 sprintf(Warn_mesg, "tst_brk(): Invalid Type: %d.
> Using TBROK",
> -                       ttype);
> +                       ttype_result);
>                 tst_print(TCID, 0, 1, TWARN, Warn_mesg);
>                 ttype = TBROK;
>         }
> @@ -641,8 +700,8 @@ void tst_brkloop(int ttype, char *fname,
>         if (ttype != TFAIL && ttype != TBROK && ttype != TCONF &&
>             ttype != TRETR) {
>                 sprintf(Warn_mesg,
> -                       "tst_brkloop(): Invalid Type: %d.  Using
> TBROK",
> -                       ttype);
> +                       "tst_brkloop(): Invalid Type: %d(%s).  Using
> TBROK",
> +                       ttype, strttype(ttype));
>                 tst_print(TCID, 0, 1, TWARN, Warn_mesg);
>                 ttype = TBROK;
>         }
> @@ -805,7 +864,6 @@ int main(void)
>  {
>         int  ttype;
>         int  range;
> -       char *chrptr;
>         char chr;
>         char fname[MAXMESG];
>  
> @@ -815,16 +873,18 @@ int main(void)
>                -3 : call tst_brk()\n\
>                -4 : call tst_brkloop()\n\
>                -5 : call tst_res() with a range\n\
> -               0 : call tst_res(TPASS, ...)\n\
> -               1 : call tst_res(TFAIL, ...)\n\
> -               2 : call tst_res(TBROK, ...)\n\
> -               4 : call tst_res(TWARN, ...)\n\
> -               8 : call tst_res(TRETR, ...)\n\
> -              16 : call tst_res(TINFO, ...)\n\
> -              32 : call tst_res(TCONF, ...)\n\n");
> +              %2i : call tst_res(TPASS, ...)\n\
> +              %2i : call tst_res(TFAIL, ...)\n\
> +              %2i : call tst_res(TBROK, ...)\n\
> +              %2i : call tst_res(TWARN, ...)\n\
> +              %2i : call tst_res(TRETR, ...)\n\
> +              %2i : call tst_res(TINFO, ...)\n\
> +              %2i : call tst_res(TCONF, ...)\n\n",
> +               TPASS, TFAIL, TBROK, TWARN, TRETR, TINFO, TCONF);
>  
>         while (1) {
> -               printf("Enter ttype (-5,-4,-3,-2,-1,0,1,2,4,8,16,32):
> ");
> +               printf("Enter ttype (-5,-4,-3,-2,-1,%i,%i,%i,%i,%i,%i,
> %i): ",
> +                       TPASS, TFAIL, TBROK, TWARN, TRETR, TINFO,
> TCONF);
>                 scanf("%d%c", &ttype, &chr);
>  
>                 switch (ttype) {
> @@ -837,7 +897,8 @@ int main(void)
>                         break;
>  
>                         case -3:
> -                               printf("Enter the current type
> (1=FAIL, 2=BROK, 8=RETR, 32=CONF): ");
> +                               printf("Enter the current type (%
> i=FAIL, %i=BROK, %i=RETR, %i=CONF): ",
> +                                       TFAIL, TBROK, TRETR, TCONF);
>                                 scanf("%d%c", &ttype, &chr);
>                                 printf("Enter file name (<cr> for
> none): ");
>                                 gets(fname);
> @@ -852,7 +913,8 @@ int main(void)
>                                 scanf("%d%c", &range, &chr);
>                                 Tst_lpstart = Tst_count;
>                                 Tst_lptotal = range;
> -                               printf("Enter the current type
> (1=FAIL, 2=BROK, 8=RETR, 32=CONF): ");
> +                               printf("Enter the current type (%
> i=FAIL, %i=BROK, %i=RETR, %i=CONF): ",
> +                                       TFAIL, TBROK, TRETR, TCONF);
>                                 scanf("%d%c", &ttype, &chr);
>                                 printf("Enter file name (<cr> for
> none): ");
>                                 gets(fname);
> @@ -866,7 +928,8 @@ int main(void)
>                         case -5:
>                                 printf("Enter the size of the range:
> ");
>                                 scanf("%d%c", &Tst_range, &chr);
> -                               printf("Enter the current type
> (0,1,2,4,8,16,32): ");
> +                               printf("Enter the current type (%i,%i,
> %i,%i,%i,%i,%i): ",
> +                                       TPASS, TFAIL, TBROK, TWARN,
> TRETR, TINFO, TCONF);
>                                 scanf("%d%c", &ttype, &chr);
>                         default:
>                                 printf("Enter file name (<cr> for
> none): ");
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> differences
> between files
> attachment
> (ltp-mmap09-ttype-masks.patch)
> 
> 
> --- testcases/kernel/syscalls/mmap/mmap09.c
> +++ testcases/kernel/syscalls/mmap/mmap09.c
> @@ -103,8 +103,7 @@ int main(int argc, char **argv)
>  
>                         if (TEST_RETURN == -1) {
>                                 TEST_ERROR_LOG(TEST_ERRNO);
> -                               tst_resm(TFAIL, "%s - errnor: %d",
> -                                        TC[i].desc, TEST_ERRNO);
> +                               tst_resm(TFAIL|TTERRNO, "%s",
> TC[i].desc);
>                         } else {
>                                 tst_resm(TPASS, TC[i].desc);
>                         }
> @@ -129,19 +128,16 @@ void setup()
>         tst_tmpdir();
>  
>         if ((fd = open("mmaptest", O_RDWR | O_CREAT, 0666)) < 0)
> -               tst_brkm(TFAIL, cleanup, "failed to open mmaptest "
> -                        "file, errno: %d", errno);
> +               tst_brkm(TFAIL|TERRNO, cleanup, "open(mmaptest) file
> failed");
>  
>         /* ftruncate the file to 16k */
>         if (ftruncate(fd, mapsize) < 0)
> -               tst_brkm(TFAIL, cleanup, "failed to ftruncate "
> -                        "file, errno: %d", errno);
> +               tst_brkm(TFAIL|TERRNO, cleanup, "ftruncate() file
> failed");
>  
>         maddr = mmap(0, (size_t) mapsize, PROT_READ | PROT_WRITE,
>                      MAP_FILE | MAP_SHARED, fd, (off_t) 0);
>         if (maddr == MAP_FAILED)
> -               tst_brkm(TFAIL, cleanup, "failed to mmap file, "
> -                        "errno: %d", errno);
> +               tst_brkm(TFAIL|TERRNO, cleanup, "mmap() file failed");
>         /* fill up the file with A's */
>         for (i = 0; i < mapsize; i++)
>                 maddr[i] = 'A';


------------------------------------------------------------------------------
Enter the BlackBerry Developer Challenge  
This is your chance to win up to $100,000 in prizes! For a limited time, 
vendors submitting new applications to BlackBerry App World(TM) will have
the opportunity to enter the BlackBerry Developer Challenge. See full prize  
details at: http://p.sf.net/sfu/Challenge
_______________________________________________
Ltp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list

Reply via email to