searchengine/util/tsrc/itk/src/itkimpl.cpp
changeset 0 671dee74050a
child 8 6547bf8ca13a
equal deleted inserted replaced
-1:000000000000 0:671dee74050a
       
     1 /*
       
     2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 #include <assert.h>
       
    19 #include <errno.h>
       
    20 #include <fcntl.h>
       
    21 #include <unistd.h>
       
    22 #include <stdio.h>
       
    23 #include <sys/types.h>
       
    24 #include <sys/stat.h>
       
    25 
       
    26 #include <fstream>
       
    27 
       
    28 #include "cpixfstools.h"
       
    29 
       
    30 #include "itktesters.h"
       
    31 #include "itktestmgr.h"
       
    32 #include "itkimpl.h"
       
    33 
       
    34 namespace
       
    35 {
       
    36     // suffix for 'in' (input to be redirected) files
       
    37     const char IN_SFX[] = "_in.txt";
       
    38 
       
    39     // suffixes for 'res' / 'exp' (RESult and EXPected) files for
       
    40     // stdandard OUTput and ERRor.
       
    41     const char RES_OUT_SFX[] = "_res_out.txt";
       
    42     const char RES_ERR_SFX[] = "_res_err.txt";
       
    43     const char EXP_OUT_SFX[] = "_exp_out.txt";
       
    44     const char EXP_ERR_SFX[] = "_exp_err.txt";
       
    45 }
       
    46 
       
    47 
       
    48 
       
    49 namespace Itk
       
    50 {
       
    51     namespace Impl
       
    52     {
       
    53 
       
    54 
       
    55         /****
       
    56          * InputRedirector
       
    57          */
       
    58         InputRedirector::InputRedirector(const std::string & defFilesBasePath)
       
    59             : duplicatedStdInFD_(-1),
       
    60               inFileFD_(-1)
       
    61         {
       
    62             using namespace std;
       
    63             using namespace Cpt;
       
    64             
       
    65             string
       
    66                 inFilePath = defFilesBasePath;
       
    67             inFilePath += IN_SFX;
       
    68             
       
    69             if (isreadable(inFilePath.c_str()))
       
    70                 {
       
    71 
       
    72                     duplicatedStdInFD_ = dup(STDIN_FILENO);
       
    73                     if (duplicatedStdInFD_ == -1)
       
    74                         {
       
    75                             throw IOCaptureExc("Can't dup(stdin)");
       
    76                         }
       
    77 
       
    78                     Cpt_EINTR_RETRY(inFileFD_,
       
    79                                     open(inFilePath.c_str(),O_RDONLY));
       
    80                     if (inFileFD_ == -1)
       
    81                         {
       
    82                         Cpt_EINTR_RETRY_SP(close(duplicatedStdInFD_));
       
    83                             throw IOCaptureExc(inFilePath.c_str());
       
    84                         }
       
    85                     int
       
    86                         newStdIn = dup2(inFileFD_,
       
    87                                         STDIN_FILENO);
       
    88                     if (newStdIn == -1)
       
    89                         {
       
    90                         Cpt_EINTR_RETRY_SP(close(inFileFD_));
       
    91                         Cpt_EINTR_RETRY_SP(close(duplicatedStdInFD_));
       
    92                             throw IOCaptureExc("Can't dup2(infile,stdin)");
       
    93                         }
       
    94                 }
       
    95         }
       
    96 
       
    97 
       
    98         InputRedirector::~InputRedirector()
       
    99         {
       
   100             if (duplicatedStdInFD_ != -1)
       
   101                 {
       
   102                     int
       
   103                         fd = dup2(duplicatedStdInFD_,
       
   104                                   STDIN_FILENO);
       
   105                     // we can't possibly do anything sensible about these
       
   106                     // failures here, but they must not go unnoticed
       
   107                     assert(fd != -1);
       
   108 
       
   109                     Cpt_EINTR_RETRY_SP(close(inFileFD_));
       
   110                     Cpt_EINTR_RETRY_SP(close(duplicatedStdInFD_));
       
   111                 }
       
   112         }
       
   113 
       
   114 
       
   115 
       
   116         /****
       
   117          * OutputRedirector
       
   118          */
       
   119         OutputRedirector::OutputRedirector(const std::string & defFilesBasePath,
       
   120                                            TestMgr           * testMgr)
       
   121             : duplicatedStdOutFD_(-1),
       
   122               outFileFD_(-1),
       
   123               stdErr_(testMgr == NULL ? true : false),
       
   124               testMgr_(testMgr)
       
   125         {
       
   126             // flushing possible STD IO stream buffers before swapping
       
   127             int
       
   128                 res = fflush(stdErr_ ? stderr : stdout);
       
   129             assert(res != EOF);
       
   130 
       
   131             using namespace std;
       
   132             
       
   133             string
       
   134                 outFilePath = defFilesBasePath;
       
   135             outFilePath += (stdErr_ ? RES_ERR_SFX : RES_OUT_SFX);
       
   136             
       
   137             int
       
   138                 stdFD = stdErr_ ? STDERR_FILENO : STDOUT_FILENO;
       
   139 
       
   140             duplicatedStdOutFD_ = dup(stdFD);
       
   141             if (duplicatedStdOutFD_ == -1)
       
   142                 {
       
   143                     const char
       
   144                         * msg = stdErr_ ? "Can't dup(stdErr)"
       
   145                         : "Can't dup(stdout)";
       
   146 
       
   147                     throw IOCaptureExc(msg);
       
   148                 }
       
   149             Cpt_EINTR_RETRY(outFileFD_,
       
   150                             open(outFilePath.c_str(),
       
   151                                  O_CREAT | O_TRUNC | O_WRONLY,
       
   152                                  0666));
       
   153             if (outFileFD_ == -1)
       
   154                 {
       
   155                     Cpt_EINTR_RETRY(res,close(duplicatedStdOutFD_));
       
   156                     throw IOCaptureExc(outFilePath.c_str());
       
   157                 }
       
   158             int
       
   159                 newStdOut = dup2(outFileFD_,
       
   160                                  stdFD);
       
   161             if (newStdOut == -1)
       
   162                 {
       
   163                     Cpt_EINTR_RETRY(res,close(outFileFD_));
       
   164                     Cpt_EINTR_RETRY(res,close(duplicatedStdOutFD_));
       
   165                     throw IOCaptureExc("Can't dup2(outfile,stdout)");
       
   166                 }
       
   167             
       
   168             if (!stdErr_)
       
   169                 {
       
   170                     testMgr_->setDbgConsoleFd(duplicatedStdOutFD_);
       
   171                 }
       
   172         }
       
   173 
       
   174 
       
   175         OutputRedirector::~OutputRedirector()
       
   176         {
       
   177             // flushing possible STD IO stream buffers before swapping
       
   178             int
       
   179                 res = fflush(stdErr_ ? stderr : stdout);
       
   180             assert(res != EOF);
       
   181 
       
   182             int
       
   183                 stdFD = stdErr_ ? STDERR_FILENO : STDOUT_FILENO;
       
   184             
       
   185             if (!stdErr_)
       
   186                 {
       
   187                     testMgr_->setDbgConsoleFd(stdFD);
       
   188                 }
       
   189 
       
   190             int
       
   191                 fd = dup2(duplicatedStdOutFD_,
       
   192                           stdFD);
       
   193             // we can't possibly do anything sensible about these
       
   194             // failures here, but they must not go unnoticed
       
   195             assert(fd != -1);
       
   196 
       
   197             Cpt_EINTR_RETRY(res,close(outFileFD_));
       
   198             Cpt_EINTR_RETRY(res,close(duplicatedStdOutFD_));
       
   199         }
       
   200 
       
   201 
       
   202         /****
       
   203          * IOCaptureEvaluator
       
   204          */
       
   205         void IOCaptureEvaluator::evaluate()
       
   206         {
       
   207             evaluate(false); // std out
       
   208             evaluate(true);  // std err
       
   209         }
       
   210 
       
   211         
       
   212         IOCaptureEvaluator
       
   213         ::IOCaptureEvaluator(const std::string  & defFileBasePath,
       
   214                              TestMgr            * testMgr,
       
   215                              const std::string  & lenience)
       
   216             : defFileBasePath_(defFileBasePath),
       
   217               testMgr_(testMgr),
       
   218               lenience_(lenience)
       
   219         {
       
   220             ;
       
   221         }
       
   222         
       
   223         void IOCaptureEvaluator::copyContent(const char * dstPath,
       
   224                                              const char * srcPath)
       
   225         {
       
   226             int
       
   227                 result = Cpt::copyFile(dstPath,
       
   228                                        srcPath);
       
   229 
       
   230             switch (result)
       
   231                 {
       
   232                 case Cpt::CPT_CPF_OK:
       
   233                     testMgr_->ioCaptureDefined(dstPath,
       
   234                                                "IO test case defined.");
       
   235                     break;
       
   236                 case Cpt::CPT_CPF_DST_OPEN_ERROR:
       
   237                     testMgr_->ioCaptureError(dstPath,
       
   238                                              "Could not open for writing");
       
   239                     break;
       
   240                 case Cpt::CPT_CPF_SRC_OPEN_ERROR:
       
   241                     testMgr_->ioCaptureError(srcPath,
       
   242                                              "Could not open for reading");
       
   243                     break;
       
   244                 case Cpt::CPT_CPF_DST_WRITE_ERROR:
       
   245                     testMgr_->ioCaptureError(dstPath,
       
   246                                              "Writing failed");
       
   247                     break;
       
   248                 case Cpt::CPT_CPF_SRC_READ_ERROR:
       
   249                     testMgr_->ioCaptureError(srcPath,
       
   250                                              "Reading failed");
       
   251                     break;
       
   252                 };
       
   253         }
       
   254 
       
   255 
       
   256         void IOCaptureEvaluator::compareContent(const char * expPath,
       
   257                                                 const char * resPath)
       
   258         {
       
   259             using namespace std;
       
   260 
       
   261             FILE*
       
   262                 expFs;
       
   263             expFs = fopen(expPath, "r");
       
   264             if (!expFs)
       
   265                 {
       
   266                     testMgr_->ioCaptureError(expPath,
       
   267                                              "Could not open for reading");
       
   268                     return;
       
   269                 }
       
   270 			Cpt::FileSentry expFsSentry( expFs ); 
       
   271 
       
   272 
       
   273             FILE*
       
   274                 resFs;
       
   275             resFs = fopen(resPath, "r");
       
   276             if (!resFs)
       
   277                 {
       
   278                     testMgr_->ioCaptureError(resPath,
       
   279                                              "Could not open for reading");
       
   280                     return;
       
   281                 }
       
   282 			Cpt::FileSentry resFsSentry( resFs ); 
       
   283 
       
   284             ssize_t
       
   285                 firstDifferingLine = -1,
       
   286                 currentLine = 1;
       
   287             string
       
   288                 expLine,
       
   289                 resLine;
       
   290             bool
       
   291                 lenient = lenience_.length() > 0;
       
   292 
       
   293             while (firstDifferingLine == -1 && Cpt::fgetline(expFs, expLine))
       
   294                 {
       
   295                     if (!Cpt::fgetline(resFs, resLine))
       
   296                         {
       
   297                             firstDifferingLine = currentLine;
       
   298                         }
       
   299                     else if (expLine != resLine)
       
   300                         {
       
   301                             if (!(lenient 
       
   302                                   && expLine.find(lenience_) != string::npos))
       
   303                                 {
       
   304                                     firstDifferingLine = currentLine;
       
   305                                 }
       
   306                         }
       
   307 
       
   308                     ++currentLine;
       
   309                 }
       
   310 
       
   311             if (firstDifferingLine == -1)
       
   312                 {
       
   313                     // If the contents were identical so far, then we
       
   314                     // have terminated the previous loop with
       
   315                     // exhausting the entire EXPected content. At this
       
   316                     // point, therefore, nothing should be left from
       
   317                     // RESult content, either.
       
   318                     if (Cpt::fgetline(resFs, resLine))
       
   319                         {
       
   320                             firstDifferingLine = currentLine;
       
   321                         }
       
   322                 }
       
   323 
       
   324             bool
       
   325                 succeeded = firstDifferingLine == -1;
       
   326 
       
   327             testMgr_->expecting(succeeded,
       
   328                                 "(IO Capture)",
       
   329                                 expPath,
       
   330                                 succeeded ? 0 : firstDifferingLine,
       
   331                                 "IO Capture test.");
       
   332         }
       
   333         
       
   334 
       
   335         void IOCaptureEvaluator::evaluate(bool stdErr)
       
   336         {
       
   337             using namespace std;
       
   338             using namespace Cpt;
       
   339 
       
   340             string
       
   341                 resPath = defFileBasePath_,
       
   342                 expPath = defFileBasePath_;
       
   343 
       
   344             resPath += (stdErr ? RES_ERR_SFX : RES_OUT_SFX);
       
   345             expPath += (stdErr ? EXP_ERR_SFX : EXP_OUT_SFX);
       
   346 
       
   347             bool
       
   348                 redirectOnly = (lenience_ == SuiteTester::REDIRECT_ONLY);
       
   349             
       
   350             if (!isreadable(resPath.c_str()))
       
   351                 {
       
   352                     testMgr_->ioCaptureError(resPath.c_str(),
       
   353                                              "Cannot open RESult file.");
       
   354                 }
       
   355             else if (isreadable(expPath.c_str()))
       
   356                 {
       
   357                     if (!redirectOnly)
       
   358                         {
       
   359                             compareContent(expPath.c_str(),
       
   360                                            resPath.c_str());
       
   361                         }
       
   362                 }
       
   363             else if (stdErr
       
   364                      && !isreadable(expPath.c_str()))
       
   365                 {
       
   366                     bool
       
   367                         succeeded = filesize(resPath.c_str()) == 0;
       
   368 
       
   369                     // if we are doing std err, and if there is no
       
   370                     // EXPected output then we fail or succeed by
       
   371                     // looking already at the size of the RESulting
       
   372                     // error
       
   373                     testMgr_->expecting(succeeded,
       
   374                                         "(IO Capture)",
       
   375                                         expPath.c_str(),
       
   376                                         0,
       
   377                                         "IO Capture test.");
       
   378                 }
       
   379             else
       
   380                 {
       
   381                     if (!redirectOnly)
       
   382                         {
       
   383                             copyContent(expPath.c_str(),
       
   384                                         resPath.c_str());
       
   385                         }
       
   386                 }
       
   387         }
       
   388 
       
   389 
       
   390 
       
   391     }
       
   392 }