searchengine/util/tsrc/itk/src/itkimpl.cpp
changeset 0 671dee74050a
child 8 6547bf8ca13a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/searchengine/util/tsrc/itk/src/itkimpl.cpp	Mon Apr 19 14:40:16 2010 +0300
@@ -0,0 +1,392 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+*
+*/
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <fstream>
+
+#include "cpixfstools.h"
+
+#include "itktesters.h"
+#include "itktestmgr.h"
+#include "itkimpl.h"
+
+namespace
+{
+    // suffix for 'in' (input to be redirected) files
+    const char IN_SFX[] = "_in.txt";
+
+    // suffixes for 'res' / 'exp' (RESult and EXPected) files for
+    // stdandard OUTput and ERRor.
+    const char RES_OUT_SFX[] = "_res_out.txt";
+    const char RES_ERR_SFX[] = "_res_err.txt";
+    const char EXP_OUT_SFX[] = "_exp_out.txt";
+    const char EXP_ERR_SFX[] = "_exp_err.txt";
+}
+
+
+
+namespace Itk
+{
+    namespace Impl
+    {
+
+
+        /****
+         * InputRedirector
+         */
+        InputRedirector::InputRedirector(const std::string & defFilesBasePath)
+            : duplicatedStdInFD_(-1),
+              inFileFD_(-1)
+        {
+            using namespace std;
+            using namespace Cpt;
+            
+            string
+                inFilePath = defFilesBasePath;
+            inFilePath += IN_SFX;
+            
+            if (isreadable(inFilePath.c_str()))
+                {
+
+                    duplicatedStdInFD_ = dup(STDIN_FILENO);
+                    if (duplicatedStdInFD_ == -1)
+                        {
+                            throw IOCaptureExc("Can't dup(stdin)");
+                        }
+
+                    Cpt_EINTR_RETRY(inFileFD_,
+                                    open(inFilePath.c_str(),O_RDONLY));
+                    if (inFileFD_ == -1)
+                        {
+                        Cpt_EINTR_RETRY_SP(close(duplicatedStdInFD_));
+                            throw IOCaptureExc(inFilePath.c_str());
+                        }
+                    int
+                        newStdIn = dup2(inFileFD_,
+                                        STDIN_FILENO);
+                    if (newStdIn == -1)
+                        {
+                        Cpt_EINTR_RETRY_SP(close(inFileFD_));
+                        Cpt_EINTR_RETRY_SP(close(duplicatedStdInFD_));
+                            throw IOCaptureExc("Can't dup2(infile,stdin)");
+                        }
+                }
+        }
+
+
+        InputRedirector::~InputRedirector()
+        {
+            if (duplicatedStdInFD_ != -1)
+                {
+                    int
+                        fd = dup2(duplicatedStdInFD_,
+                                  STDIN_FILENO);
+                    // we can't possibly do anything sensible about these
+                    // failures here, but they must not go unnoticed
+                    assert(fd != -1);
+
+                    Cpt_EINTR_RETRY_SP(close(inFileFD_));
+                    Cpt_EINTR_RETRY_SP(close(duplicatedStdInFD_));
+                }
+        }
+
+
+
+        /****
+         * OutputRedirector
+         */
+        OutputRedirector::OutputRedirector(const std::string & defFilesBasePath,
+                                           TestMgr           * testMgr)
+            : duplicatedStdOutFD_(-1),
+              outFileFD_(-1),
+              stdErr_(testMgr == NULL ? true : false),
+              testMgr_(testMgr)
+        {
+            // flushing possible STD IO stream buffers before swapping
+            int
+                res = fflush(stdErr_ ? stderr : stdout);
+            assert(res != EOF);
+
+            using namespace std;
+            
+            string
+                outFilePath = defFilesBasePath;
+            outFilePath += (stdErr_ ? RES_ERR_SFX : RES_OUT_SFX);
+            
+            int
+                stdFD = stdErr_ ? STDERR_FILENO : STDOUT_FILENO;
+
+            duplicatedStdOutFD_ = dup(stdFD);
+            if (duplicatedStdOutFD_ == -1)
+                {
+                    const char
+                        * msg = stdErr_ ? "Can't dup(stdErr)"
+                        : "Can't dup(stdout)";
+
+                    throw IOCaptureExc(msg);
+                }
+            Cpt_EINTR_RETRY(outFileFD_,
+                            open(outFilePath.c_str(),
+                                 O_CREAT | O_TRUNC | O_WRONLY,
+                                 0666));
+            if (outFileFD_ == -1)
+                {
+                    Cpt_EINTR_RETRY(res,close(duplicatedStdOutFD_));
+                    throw IOCaptureExc(outFilePath.c_str());
+                }
+            int
+                newStdOut = dup2(outFileFD_,
+                                 stdFD);
+            if (newStdOut == -1)
+                {
+                    Cpt_EINTR_RETRY(res,close(outFileFD_));
+                    Cpt_EINTR_RETRY(res,close(duplicatedStdOutFD_));
+                    throw IOCaptureExc("Can't dup2(outfile,stdout)");
+                }
+            
+            if (!stdErr_)
+                {
+                    testMgr_->setDbgConsoleFd(duplicatedStdOutFD_);
+                }
+        }
+
+
+        OutputRedirector::~OutputRedirector()
+        {
+            // flushing possible STD IO stream buffers before swapping
+            int
+                res = fflush(stdErr_ ? stderr : stdout);
+            assert(res != EOF);
+
+            int
+                stdFD = stdErr_ ? STDERR_FILENO : STDOUT_FILENO;
+            
+            if (!stdErr_)
+                {
+                    testMgr_->setDbgConsoleFd(stdFD);
+                }
+
+            int
+                fd = dup2(duplicatedStdOutFD_,
+                          stdFD);
+            // we can't possibly do anything sensible about these
+            // failures here, but they must not go unnoticed
+            assert(fd != -1);
+
+            Cpt_EINTR_RETRY(res,close(outFileFD_));
+            Cpt_EINTR_RETRY(res,close(duplicatedStdOutFD_));
+        }
+
+
+        /****
+         * IOCaptureEvaluator
+         */
+        void IOCaptureEvaluator::evaluate()
+        {
+            evaluate(false); // std out
+            evaluate(true);  // std err
+        }
+
+        
+        IOCaptureEvaluator
+        ::IOCaptureEvaluator(const std::string  & defFileBasePath,
+                             TestMgr            * testMgr,
+                             const std::string  & lenience)
+            : defFileBasePath_(defFileBasePath),
+              testMgr_(testMgr),
+              lenience_(lenience)
+        {
+            ;
+        }
+        
+        void IOCaptureEvaluator::copyContent(const char * dstPath,
+                                             const char * srcPath)
+        {
+            int
+                result = Cpt::copyFile(dstPath,
+                                       srcPath);
+
+            switch (result)
+                {
+                case Cpt::CPT_CPF_OK:
+                    testMgr_->ioCaptureDefined(dstPath,
+                                               "IO test case defined.");
+                    break;
+                case Cpt::CPT_CPF_DST_OPEN_ERROR:
+                    testMgr_->ioCaptureError(dstPath,
+                                             "Could not open for writing");
+                    break;
+                case Cpt::CPT_CPF_SRC_OPEN_ERROR:
+                    testMgr_->ioCaptureError(srcPath,
+                                             "Could not open for reading");
+                    break;
+                case Cpt::CPT_CPF_DST_WRITE_ERROR:
+                    testMgr_->ioCaptureError(dstPath,
+                                             "Writing failed");
+                    break;
+                case Cpt::CPT_CPF_SRC_READ_ERROR:
+                    testMgr_->ioCaptureError(srcPath,
+                                             "Reading failed");
+                    break;
+                };
+        }
+
+
+        void IOCaptureEvaluator::compareContent(const char * expPath,
+                                                const char * resPath)
+        {
+            using namespace std;
+
+            FILE*
+                expFs;
+            expFs = fopen(expPath, "r");
+            if (!expFs)
+                {
+                    testMgr_->ioCaptureError(expPath,
+                                             "Could not open for reading");
+                    return;
+                }
+			Cpt::FileSentry expFsSentry( expFs ); 
+
+
+            FILE*
+                resFs;
+            resFs = fopen(resPath, "r");
+            if (!resFs)
+                {
+                    testMgr_->ioCaptureError(resPath,
+                                             "Could not open for reading");
+                    return;
+                }
+			Cpt::FileSentry resFsSentry( resFs ); 
+
+            ssize_t
+                firstDifferingLine = -1,
+                currentLine = 1;
+            string
+                expLine,
+                resLine;
+            bool
+                lenient = lenience_.length() > 0;
+
+            while (firstDifferingLine == -1 && Cpt::fgetline(expFs, expLine))
+                {
+                    if (!Cpt::fgetline(resFs, resLine))
+                        {
+                            firstDifferingLine = currentLine;
+                        }
+                    else if (expLine != resLine)
+                        {
+                            if (!(lenient 
+                                  && expLine.find(lenience_) != string::npos))
+                                {
+                                    firstDifferingLine = currentLine;
+                                }
+                        }
+
+                    ++currentLine;
+                }
+
+            if (firstDifferingLine == -1)
+                {
+                    // If the contents were identical so far, then we
+                    // have terminated the previous loop with
+                    // exhausting the entire EXPected content. At this
+                    // point, therefore, nothing should be left from
+                    // RESult content, either.
+                    if (Cpt::fgetline(resFs, resLine))
+                        {
+                            firstDifferingLine = currentLine;
+                        }
+                }
+
+            bool
+                succeeded = firstDifferingLine == -1;
+
+            testMgr_->expecting(succeeded,
+                                "(IO Capture)",
+                                expPath,
+                                succeeded ? 0 : firstDifferingLine,
+                                "IO Capture test.");
+        }
+        
+
+        void IOCaptureEvaluator::evaluate(bool stdErr)
+        {
+            using namespace std;
+            using namespace Cpt;
+
+            string
+                resPath = defFileBasePath_,
+                expPath = defFileBasePath_;
+
+            resPath += (stdErr ? RES_ERR_SFX : RES_OUT_SFX);
+            expPath += (stdErr ? EXP_ERR_SFX : EXP_OUT_SFX);
+
+            bool
+                redirectOnly = (lenience_ == SuiteTester::REDIRECT_ONLY);
+            
+            if (!isreadable(resPath.c_str()))
+                {
+                    testMgr_->ioCaptureError(resPath.c_str(),
+                                             "Cannot open RESult file.");
+                }
+            else if (isreadable(expPath.c_str()))
+                {
+                    if (!redirectOnly)
+                        {
+                            compareContent(expPath.c_str(),
+                                           resPath.c_str());
+                        }
+                }
+            else if (stdErr
+                     && !isreadable(expPath.c_str()))
+                {
+                    bool
+                        succeeded = filesize(resPath.c_str()) == 0;
+
+                    // if we are doing std err, and if there is no
+                    // EXPected output then we fail or succeed by
+                    // looking already at the size of the RESulting
+                    // error
+                    testMgr_->expecting(succeeded,
+                                        "(IO Capture)",
+                                        expPath.c_str(),
+                                        0,
+                                        "IO Capture test.");
+                }
+            else
+                {
+                    if (!redirectOnly)
+                        {
+                            copyContent(expPath.c_str(),
+                                        resPath.c_str());
+                        }
+                }
+        }
+
+
+
+    }
+}