Index: src/lib/tests/pipelineTester.c
===================================================================
RCS file: /projects/compbio/cvsroot/kent/src/lib/tests/pipelineTester.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -b -B -U 1000000 -r1.4 -r1.5
--- src/lib/tests/pipelineTester.c	4 Aug 2006 06:00:20 -0000	1.4
+++ src/lib/tests/pipelineTester.c	19 Dec 2009 00:23:21 -0000	1.5
@@ -1,290 +1,275 @@
 /* pipelineTester - test program for pipeline object */
 #include "common.h"
 #include "pipeline.h"
 #include "linefile.h"
 #include "options.h"
 
 static char const rcsid[] = "$Id$";
 
 void usage(char *msg)
 /* Explain usage and exit. */
 {
 errAbort(
     "%s\n\n"
     "pipelineTester - test program for pipeline object\n"
     "\n"
     "Usage:\n"
     "   pipelineTester [options] cmdArgs1 [cmdArgs2 ..]\n"
     "\n"
     "Each cmdArgs are a command and whitespace separated\n"
     "arguments to pipe together.  Within a cmdArgs, single or\n"
     "double quote maybe used to quote words.\n"
     "\n"
     "Options:\n"
     "  -exitCode=n - run with no-abort and expect this error code,\n"
     "   which can be zero.\n"
     "  -write - create a write pipeline\n"
     "  -memApi - test memory buffer API\n"
     "  -pipeData=file - for a read pipeline, data read from the pipeline is copied\n"
     "   to this file for verification.  For a write pipeline, data from this\n"
     "   file is written to the pipeline.\n"
     "  -otherEnd=file - file for other end of pipeline\n"
     "  -stderr=file - file for stderr of pipeline\n"
     "  -fdApi - use the file descriptor API\n",
     msg);
 }
 
 static struct optionSpec options[] =
 {
     {"exitCode", OPTION_INT},
     {"write", OPTION_BOOLEAN},
     {"memApi", OPTION_BOOLEAN},
     {"pipeData", OPTION_STRING},
     {"otherEnd", OPTION_STRING},
     {"stderr", OPTION_STRING},
     {"fdApi", OPTION_BOOLEAN},
     {NULL, 0},
 };
 
 /* options from command line */
 boolean noAbort = FALSE;  /* don't abort, check exit code */
 int expectExitCode = 0;   /* expected exit code */
 boolean fdApi = FALSE; /* use the file descriptor API */
 boolean isWrite = FALSE; /* make a write pipeline */
 boolean memApi = FALSE; /* test memory buffer API */
 char *pipeDataFile = NULL;   /* use for input or output to the pipeline */
 char *otherEndFile = NULL;   /* file for other end of pipeline */
 char *stderrFile = NULL;   /* file for other stderr of pipeline */
 
 int countOpenFiles()
 /* count the number of opens.  This is used to make sure no stray
  * pipes have been left open. */
 {
 int cnt = 0;
 int fd;
 struct stat statBuf;
 for (fd = 0; fd < 64; fd++)
     {
     if (fstat(fd, &statBuf) == 0)
         cnt++;
     }
 return cnt;
 }
 
-int mustOpenFd(char *fname, boolean isWrite)
-/* open a file, returning a descriptor or aborting */
-{
-int fd = open(fname, (isWrite ? O_WRONLY|O_CREAT|O_TRUNC : O_RDONLY), 0777);
-if (fd < 0)
-    errnoAbort("open of %s failed", fname);
-return fd;
-}
-
-void mustCloseFd(int fd)
-/* close a file, abort on an error */
-{
-if (close(fd) < 0)
-    errnoAbort("close failed");
-}
-
 char *parseQuoted(char **spPtr, char *cmdArgs)
 /* parse a quoted string */
 {
 char *start = *spPtr;
 char quote = *start++;
 char *end = strchr(start, quote);
 if (end == NULL)
     errAbort("no closing quote in: %s", cmdArgs);
 *spPtr = end+1;
 return cloneStringZ(start, end-start);
 }
 
 char **splitCmd(char *cmdArgs)
 /* split a command and arguments into null termiated list, handling quoting */
 {
 // this will get the maximum number of words, as it doesn't consider quoting
 int maxNumWords = chopByWhite(cmdArgs, NULL, 0);
 char **words = needMem((maxNumWords+1)*sizeof(char*));
 int iWord = 0;
 char *sp = skipLeadingSpaces(cmdArgs);
 
 while (*sp != '\0')
     {
     assert(iWord < maxNumWords);
     if ((*sp == '"') || (*sp == '\''))
         words[iWord++] = parseQuoted(&sp, cmdArgs);
     else
         {
         char *end = skipToSpaces(sp);
         if (end == NULL)
             end = sp + strlen(sp);
         words[iWord++] = cloneStringZ(sp, (end - sp));
         sp = end;
         }
     sp = skipLeadingSpaces(sp);
     }
 return words;
 }
 
 char ***splitCmds(int nCmdsArgs, char **cmdsArgs)
 /* split all commands into a pipeline */
 {
 char ***cmds = needMem((nCmdsArgs+1)*sizeof(char**));
 int i;
 for (i = 0; i < nCmdsArgs; i++)
     cmds[i] = splitCmd(cmdsArgs[i]);
 return cmds;
 }
 
 void readTest(struct pipeline *pl)
 /* test a read pipeline */
 {
 struct lineFile *pipeLf = pipelineLineFile(pl);
 FILE *dataFh = mustOpen(pipeDataFile, "w");
 char *line;
 
 while (lineFileNext(pipeLf, &line, NULL))
     {
     fputs(line, dataFh);
     fputc('\n', dataFh);
     if (ferror(dataFh))
         errnoAbort("error writing data from pipeline to: %s", pipeDataFile);
     }
 
 carefulClose(&dataFh);
 }
 
 void writeTest(struct pipeline *pl)
 /* test a write pipeline */
 {
 FILE *pipeFh = pipelineFile(pl);
 struct lineFile *dataLf = lineFileOpen(pipeDataFile, TRUE);
 char *line;
 
 while (lineFileNext(dataLf, &line, NULL))
     {
     fputs(line, pipeFh);
     fputc('\n', pipeFh);
     if (ferror(pipeFh))
         errnoAbort("error writing data to pipeline: %s", pipelineDesc(pl));
     }
 
 lineFileClose(&dataLf);
 }
 
 void *loadMemData(char *dataFile, size_t *dataSizeRet)
 /* load a file into memory */
 {
 off_t dataSize = fileSize(dataFile);
 void *buf = needLargeMem(dataSize);
 FILE *fh = mustOpen(dataFile, "r");
 
 mustRead(fh, buf, dataSize);
 carefulClose(&fh);
 *dataSizeRet = dataSize;
 return buf;
 }
 
 void runPipelineTest(struct pipeline *pl)
 /* execute and validate test once pipeline has been created */
 {
 /* if no data file is specified, we just let the pipeline run without
  * interacting with it */
 if (pipeDataFile != NULL)
     {
     if (isWrite)
         writeTest(pl);
     else
         readTest(pl);
     }
 int exitCode = pipelineWait(pl);
 if (exitCode != expectExitCode)
     errAbort("expected exitCode %d, got %d", expectExitCode, exitCode);
 }
 
 void pipelineTestFd(char ***cmds, unsigned options)
 /* test for file descriptor API */
 {
-int otherEndFd = mustOpenFd(otherEndFile, isWrite);
+int mode = (isWrite ? O_WRONLY|O_CREAT|O_TRUNC : O_RDONLY);
+int otherEndFd = mustOpenFd(otherEndFile, mode);
 int stderrFd = (stderrFile == NULL) ? STDERR_FILENO
-    : mustOpenFd(stderrFile, TRUE);
+    : mustOpenFd(stderrFile, O_WRONLY|O_CREAT|O_TRUNC);
 struct pipeline *pl = pipelineOpenFd(cmds, options, otherEndFd, stderrFd);
 runPipelineTest(pl);
 pipelineFree(&pl);
-mustCloseFd(otherEndFd);
+mustCloseFd(&otherEndFd);
 if (stderrFile != NULL)
-    mustCloseFd(stderrFd);
+    mustCloseFd(&stderrFd);
 }
 
 void pipelineTestMem(char ***cmds, unsigned options)
 /* test for memory buffer API */
 {
 int stderrFd = (stderrFile == NULL) ? STDERR_FILENO
-    : mustOpenFd(stderrFile, TRUE);
+    : mustOpenFd(stderrFile, O_WRONLY|O_CREAT|O_TRUNC);
 size_t otherEndBufSize = 0;
 void *otherEndBuf = loadMemData(otherEndFile, &otherEndBufSize);
 struct pipeline *pl = pipelineOpenMem(cmds, options, otherEndBuf, otherEndBufSize, stderrFd);
 runPipelineTest(pl);
 pipelineFree(&pl);
 freeMem(otherEndBuf);
 if (stderrFile != NULL)
-    mustCloseFd(stderrFd);
+    mustCloseFd(&stderrFd);
 }
 
 void pipelineTestFName(char ***cmds, unsigned options)
 /* test for file name API */
 {
 struct pipeline *pl = pipelineOpen(cmds, options, otherEndFile, stderrFile);
 runPipelineTest(pl);
 pipelineFree(&pl);
 }
 
 void pipelineTester(int nCmdsArgs, char **cmdsArgs)
 /* pipeline tester */
 {
 unsigned options = (isWrite ? pipelineWrite : pipelineRead);
 if (noAbort)
     options |= pipelineNoAbort;
 int startOpenCnt = countOpenFiles();
 char ***cmds = splitCmds(nCmdsArgs, cmdsArgs);
 
 if (fdApi)
     pipelineTestFd(cmds, options);
 else if (memApi)
     pipelineTestMem(cmds, options);
 else
     pipelineTestFName(cmds, options);
 
 /* it's ok to have less open, as would happen if we read from stdin */
 int endOpenCnt = countOpenFiles();
 if (endOpenCnt > startOpenCnt)
     errAbort("started with %d files open, now have %d open", startOpenCnt,
              endOpenCnt);
 }
 
 int main(int argc, char *argv[])
 /* Process command line. */
 {
 optionInit(&argc, argv, options);
 if (argc < 2)
     usage("wrong number of args");
 if (optionExists("exitCode"))
     {
     noAbort = TRUE;
     expectExitCode = optionInt("exitCode", 0);
     }
 isWrite = optionExists("write");
 memApi = optionExists("memApi");
 fdApi = optionExists("fdApi");
 if (fdApi && memApi)
     errAbort("can't specify both -fdApi and -memApi");
 pipeDataFile = optionVal("pipeData", NULL);
 otherEndFile = optionVal("otherEnd", NULL);
 if (fdApi && (otherEndFile == NULL))
     errAbort("-fdApi requires -otherEndFile");
 if (memApi && (otherEndFile == NULL))
     errAbort("-memApi requires -otherEndFile");
 stderrFile = optionVal("stderr", NULL);
 pipelineTester(argc-1, argv+1);
 return 0;
 }

