--- /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());
+ }
+ }
+ }
+
+
+
+ }
+}