--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/searchengine/cpix/tsrc/cpixunittest/src/testutils.cpp Mon Apr 19 14:40:16 2010 +0300
@@ -0,0 +1,821 @@
+/*
+* 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 <dirent.h>
+#include <errno.h>
+#include <wchar.h>
+#include <stddef.h>
+
+#include <iostream>
+#include <sstream>
+#include <fstream>
+
+#include "cpixidxdb.h"
+
+#include "itk.h"
+
+#include "config.h"
+
+
+
+#include "testutils.h"
+
+std::wstring GetItemId(int itemIndex)
+{
+ using namespace std;
+
+ wostringstream
+ id;
+
+ if (itemIndex == 0)
+ {
+ id << (wchar_t)'a';
+ }
+ else
+ {
+ // smallest first
+ while (itemIndex > 0) {
+ id << (wchar_t)('a'+(itemIndex%10));
+ itemIndex/=10;
+ }
+ }
+
+ return id.str();
+}
+
+
+int GetItemIndex(const wchar_t * itemId)
+{
+ int
+ ret = 0,
+ exp = 1;
+
+ size_t
+ length = wcslen(itemId);
+
+ for (size_t i = 0; i < length; ++i) {
+ if ( itemId[i] >= 'a' && itemId[i] < 'a'+10) {
+ ret += (itemId[i]-'a') * exp;
+ exp*=10;
+ } else {
+ // TODO: Panic
+ return -1;
+ }
+ }
+
+ return ret;
+}
+
+
+
+void PrintHit(cpix_Document * doc,
+ Itk::TestMgr * testMgr)
+{
+ using namespace std;
+
+ const wchar_t
+ * value = cpix_Document_getFieldValue(doc,
+ LCPIX_DOCUID_FIELD);
+
+ // path-case: if it looks like path starting with a drive letter
+ // and a colon-separator, then get rid of the drive letter to be
+ // able to pass test cases both on the phone and the emulator
+ wstring
+ docUid(value);
+ if (docUid.length() > 2
+ && docUid[1] == L':')
+ {
+ docUid[0] = L'!';
+ }
+
+ ITK_EXPECT(testMgr, value != NULL, "DOCUID field not found");
+
+ fprintf(stdout,
+ "DOC (%S): ",
+ docUid.c_str());
+
+ value = cpix_Document_getFieldValue(doc,
+ LCPIX_EXCERPT_FIELD);
+
+ ITK_EXPECT(testMgr, value != NULL, "EXCERPT field not found");
+
+ fprintf(stdout,
+ "%S\n",
+ value);
+}
+
+
+void PrintHits(cpix_Hits * hits,
+ Itk::TestMgr * testMgr)
+{
+ CustomPrintHits(hits,
+ testMgr,
+ &PrintHit);
+}
+
+
+void CustomPrintHits(cpix_Hits * hits,
+ Itk::TestMgr * testMgr,
+ void (* printHitFunc)(cpix_Document *, Itk::TestMgr *))
+{
+ using namespace std;
+
+ int32_t
+ hitCount = cpix_Hits_length(hits);
+
+ if (cpix_Failed(hits))
+ {
+ ITK_EXPECT(testMgr,
+ false,
+ "Failed to get number of hits");
+ cpix_ClearError(hits);
+ return;
+ }
+
+ cout << "Number of hits: " << hitCount << endl;
+
+ cpix_Document
+ doc;
+
+ for (int32_t i = 0; i < hitCount; ++i)
+ {
+ cpix_Hits_doc(hits,
+ i,
+ &doc);
+
+ if (cpix_Failed(hits))
+ {
+ ITK_EXPECT(testMgr,
+ false,
+ "Failed to get doc %d",
+ i);
+ cpix_ClearError(hits);
+ break;
+ }
+ // OBS PrintHit(&doc,
+ printHitFunc(&doc,
+ testMgr);
+ }
+}
+
+
+
+
+IdxUtil::IdxUtil()
+ : idxDb_(NULL),
+ schemaId_(0)
+{
+ ;
+}
+
+void IdxUtil::init(bool create) throw (Itk::PanicExc)
+{
+ cpix_Result
+ result;
+
+ if (create)
+ {
+ cpix_IdxDb_defineVolume(&result,
+ qualBaseAppClass(),
+ idxDbPath());
+
+ if (cpix_Succeeded(&result))
+ {
+ idxDb_ = cpix_IdxDb_openDb(&result,
+ qualBaseAppClass(),
+ cpix_IDX_CREATE);
+ }
+ }
+ else
+ {
+ idxDb_ = cpix_IdxDb_openDb(&result,
+ qualBaseAppClass(),
+ cpix_IDX_OPEN);
+ }
+
+ if (idxDb_ == NULL)
+ {
+ wchar_t
+ report[256];
+
+ cpix_Error_report(result.err_,
+ report,
+ sizeof(report) / sizeof(wchar_t));
+
+ ITK_PANIC("Could not create/open idx db '%s' for '%s - %S'",
+ idxDbPath(),
+ qualBaseAppClass(),
+ report);
+ }
+
+ schemaId_ = addSchema();
+}
+
+void IdxUtil::reload() throw (Itk::PanicExc)
+{
+ cpix_Result
+ result;
+
+ cpix_IdxDb_releaseDb(idxDb_);
+ idxDb_ = NULL;
+ schemaId_ = NULL;
+
+ idxDb_ = cpix_IdxDb_openDb(&result,
+ qualBaseAppClass(),
+ cpix_IDX_OPEN);
+
+ if (idxDb_ == NULL)
+ {
+ ITK_PANIC("Could not reopen idx db '%s' for '%s'",
+ idxDbPath(),
+ qualBaseAppClass());
+ }
+
+ schemaId_ = addSchema();
+}
+
+void IdxUtil::recreate() throw (Itk::PanicExc)
+{
+ cpix_Result
+ result;
+
+ cpix_IdxDb_releaseDb(idxDb_);
+ idxDb_ = NULL;
+ schemaId_ = NULL;
+
+ cpix_IdxDb_defineVolume(&result,
+ qualBaseAppClass(),
+ idxDbPath());
+ if (cpix_Succeeded(&result))
+ {
+ idxDb_ = cpix_IdxDb_openDb(&result,
+ qualBaseAppClass(),
+ cpix_IDX_CREATE);
+ }
+
+ if (idxDb_ == NULL)
+ {
+ ITK_PANIC("Could not reopen idx db '%s' for '%s'",
+ idxDbPath(),
+ qualBaseAppClass());
+ }
+
+ schemaId_ = addSchema();
+}
+
+void IdxUtil::flush() throw (Itk::PanicExc)
+{
+ cpix_IdxDb_flush( idxDb_ );
+
+ if ( cpix_Failed( idxDb_ ) )
+ {
+ ITK_PANIC("Could not flush idx db '%s' for '%s'",
+ idxDbPath(),
+ qualBaseAppClass());
+ }
+}
+
+void IdxUtil::close() throw()
+{
+ if ( idxDb_ )
+ {
+ cpix_IdxDb_releaseDb(idxDb_);
+ idxDb_ = 0;
+ }
+}
+
+IdxUtil::~IdxUtil() throw()
+{
+ close();
+}
+
+
+void IdxUtil::printHits(cpix_Hits * hits,
+ Itk::TestMgr * testMgr,
+ bool allowFailure)
+{
+ using namespace std;
+
+ int32_t
+ hitCount = cpix_Hits_length(hits);
+
+ if (cpix_Failed(hits))
+ {
+ ITK_EXPECT(testMgr,
+ false,
+ "Failed to get number of hits");
+ cpix_ClearError(hits);
+ return;
+ }
+
+ cout << "Number of hits: " << hitCount << endl;
+
+ cpix_Document
+ doc;
+
+ for (int32_t i = 0; i < hitCount; ++i)
+ {
+ cpix_Hits_doc(hits,
+ i,
+ &doc);
+
+ if (cpix_Failed(hits))
+ {
+ if (allowFailure)
+ {
+ printf("Failed to get doc %d - updated index?\n",
+ i);
+ }
+ else
+ {
+ ITK_EXPECT(testMgr,
+ false,
+ "Failed to get doc %d",
+ i);
+ }
+
+ cpix_ClearError(hits);
+ break;
+ }
+ printHit(&doc,
+ testMgr);
+ }
+}
+
+
+cpix_IdxDb * IdxUtil::idxDb()
+{
+ return idxDb_;
+}
+
+
+SchemaId IdxUtil::schemaId()
+{
+ return schemaId_;
+}
+
+
+void IdxUtil::printHit(cpix_Document * doc,
+ Itk::TestMgr * testMgr)
+{
+ using namespace std;
+
+ std::wstring
+ idStr(getIdStr(doc,
+ testMgr));
+
+ fprintf(stdout,
+ "DOC (%S): ",
+ idStr.c_str());
+
+ const wchar_t
+ * value = cpix_Document_getFieldValue(doc,
+ LCPIX_EXCERPT_FIELD);
+
+ ITK_EXPECT(testMgr, value != NULL, "EXCERPT field not found");
+
+ fprintf(stdout,
+ "%S\n",
+ value);
+}
+
+
+
+/****
+ * SmsIdxUtil
+ */
+SmsIdxUtil::SmsIdxUtil(const char * qbac)
+ : qbac_(qbac)
+{
+ ;
+}
+
+
+SmsIdxUtil::~SmsIdxUtil() throw ()
+{
+ ;
+}
+
+
+const char * SmsIdxUtil::qualBaseAppClass() const
+{
+ return qbac_.c_str();
+}
+
+
+const char * SmsIdxUtil::idxDbPath() const
+{
+ return NULL;
+}
+
+
+cpix_FieldDesc SmsSchema[] = {
+
+ // NOTE: in an actual SMS schema, you would probably not want to
+ // store fields "to", "from" and "folder".
+
+ {
+ LTO_FIELD, // name_
+ cpix_STORE_YES | cpix_INDEX_UNTOKENIZED, // cfg_
+ },
+ {
+ LFROM_FIELD, // name_
+ cpix_STORE_YES | cpix_INDEX_UNTOKENIZED, // cfg_
+ },
+ {
+ LFOLDER_FIELD, // name_
+ cpix_STORE_YES | cpix_INDEX_UNTOKENIZED, // cfg_
+ },
+ {
+ LBODY_FIELD, // name_
+ cpix_STORE_NO | cpix_INDEX_TOKENIZED, // cfg_
+ },
+
+};
+
+
+
+SchemaId SmsIdxUtil::addSchema() throw (Itk::PanicExc)
+{
+ SchemaId
+ rv = cpix_IdxDb_addSchema(idxDb(),
+ SmsSchema,
+ sizeof(SmsSchema)/sizeof(cpix_FieldDesc));
+ if (cpix_Failed(idxDb()))
+ {
+ cpix_ClearError(idxDb());
+ ITK_PANIC("Failed to add SMS schema");
+ }
+
+ return rv;
+}
+
+
+void SmsIdxUtil::deleteSms(size_t id,
+ Itk::TestMgr * testMgr)
+{
+ std::wstring
+ docUid = GetItemId(id);
+
+ int32_t
+ result = cpix_IdxDb_deleteDocuments(idxDb(),
+ docUid.c_str());
+
+
+ ITK_EXPECT(testMgr,
+ cpix_Succeeded(idxDb()),
+ "Failed to delete by %S",
+ docUid.c_str());
+
+ if (cpix_Succeeded(idxDb()))
+ {
+ ITK_MSG(testMgr,
+ "Deleted %d items by %S",
+ result,
+ docUid.c_str());
+ }
+}
+
+
+void SmsIdxUtil::indexSms(size_t id,
+ const wchar_t * body,
+ cpix_Analyzer * analyzer,
+ Itk::TestMgr * testMgr,
+ bool update)
+{
+ using namespace std;
+
+ wstring
+ docUid = GetItemId(id);
+
+ /* TEMP
+ currently we are going to use the full SMS body as excerpt
+ for testing purposes, but otherwise this piece of code could
+ do excerpt generation.
+ wchar_t
+ excerpt[128];
+ cpix_EPIState
+ epiState;
+ size_t
+ maxWords = 6,
+ bufSize = sizeof(excerpt) / sizeof(wchar_t);
+ cpix_init_EPIState(&epiState);
+ cpix_getExcerptOfWText(excerpt,
+ body,
+ &maxWords,
+ &bufSize,
+ &epiState);
+ */
+
+ const wchar_t
+ * fields[4];
+ fields[0] = L"+3585553412"; // to
+ fields[1] = L"+3585559078"; // from
+ fields[2] = L"inbox"; // folder
+ fields[3] = body; // body
+
+ void (*op)(cpix_IdxDb*,
+ SchemaId,
+ const wchar_t*,
+ const char*,
+ const wchar_t*,
+ const wchar_t*,
+ const wchar_t**,
+ cpix_Analyzer*) = &cpix_IdxDb_add2;
+ const char
+ * okFormatStr = "Indexed SMS %d",
+ * failureStr = "Failed to index SMS";
+
+ if (update)
+ {
+ op = &cpix_IdxDb_update2;
+ okFormatStr = "Updated SMS %d";
+ failureStr = "Failed to update SMS";
+ }
+
+ op(idxDb(),
+ schemaId(),
+ docUid.c_str(), // doc uid
+ SMSAPPCLASS, // app class
+ // TEMP excerpt, // excerpt
+ body, // (as) excerpt
+ NULL, // app id
+ fields, // fields
+ analyzer);
+
+ if (cpix_Succeeded(idxDb()))
+ {
+ ITK_MSG(testMgr,
+ okFormatStr,
+ id);
+ }
+ else
+ {
+ wchar_t
+ report[256];
+ cpix_Error_report(idxDb()->err_,
+ report,
+ sizeof(report) / sizeof(wchar_t));
+
+ ITK_EXPECT(testMgr,
+ false,
+ "%s %d: %S",
+ failureStr,
+ id,
+ report);
+
+ cpix_ClearError(idxDb());
+ }
+}
+
+
+std::wstring SmsIdxUtil::getIdStr(cpix_Document * doc,
+ Itk::TestMgr * testMgr)
+{
+ const wchar_t
+ * value = cpix_Document_getFieldValue(doc,
+ LCPIX_DOCUID_FIELD);
+
+ ITK_EXPECT(testMgr, value != NULL, "DOCUID field not found");
+
+ std::wstring
+ rv(value);
+
+ rv += L", line ";
+
+ wchar_t
+ dummy[32];
+ snwprintf(dummy,
+ sizeof(dummy) / sizeof(wchar_t),
+ L"%d",
+ GetItemIndex(value) + 1);
+
+ rv += dummy;
+
+ return rv;
+}
+
+
+/****
+ * FileIdxUtil
+ */
+FileIdxUtil::~FileIdxUtil() throw ()
+{
+ ;
+}
+
+
+void FileIdxUtil::indexFile(const char * path,
+ cpix_Analyzer * analyzer,
+ Itk::TestMgr * testMgr)
+{
+ wchar_t
+ wpath[256];
+
+ size_t
+ res = mbstowcs(wpath,
+ path,
+ sizeof(wpath) / sizeof(wchar_t) - 1);
+ ITK_ASSERT(testMgr,
+ //res >= 0,
+ 1,
+ "mbstowcs failed, errno: %d",
+ errno);
+ wpath[sizeof(wpath) / sizeof(wchar_t) - 1] = wchar_t(0);
+
+ /* THIS IS ALSO POSSIBLE
+ cpix_IdxDb_add2(idxDb(),
+ schemaId(),
+ wpath, // docUid,
+ TEXTAPPCLASS, // app class
+ NULL, // excerpt file parser defined
+ NULL, // app id
+ (const wchar_t**)&field, // fields: { cpix_FILTERID_FIELD }
+ analyzer);
+ */
+
+
+ // Using here the non-schema based addition method
+ // o creating document
+ // o populating it
+ // o adding it
+ // NOTE: app class, excerpt and mime type have to be defined
+ // here, but this is using the file parser functionality
+ // inside Cpix, which re-defines these anyway
+ cpix_Result
+ result;
+ cpix_Document
+ * doc = cpix_Document_create(&result,
+ wpath, // docUid,
+ NULL, // app class
+ NULL, // excerpt (file parser d)
+ NULL); // mime type
+
+ wchar_t
+ report[512];
+
+ if (cpix_Failed(&result))
+ {
+ cpix_Error_report(result.err_,
+ report,
+ sizeof(report)/sizeof(wchar_t));
+ ITK_EXPECT(testMgr,
+ false,
+ "Failed to create document %S: %S",
+ wpath,
+ report);
+ cpix_ClearError(&result);
+ return;
+ }
+
+ cpix_Field
+ filterIdField;
+
+ cpix_Field_initialize(&filterIdField,
+ LCPIX_FILTERID_FIELD,
+ LCPIX_FILEPARSER_FID,
+ cpix_STORE_YES | cpix_INDEX_NO);
+
+ if (cpix_Failed(&filterIdField))
+ {
+ cpix_Error_report(filterIdField.err_,
+ report,
+ sizeof(report)/sizeof(wchar_t));
+ ITK_EXPECT(testMgr,
+ false,
+ "Failed to create field");
+ cpix_ClearError(&filterIdField);
+ cpix_Document_destroy(doc);
+ return;
+ }
+
+ cpix_Document_add(doc,
+ &filterIdField);
+
+ if (cpix_Failed(doc))
+ {
+ cpix_Error_report(doc->err_,
+ report,
+ sizeof(report)/sizeof(wchar_t));
+ ITK_EXPECT(testMgr,
+ false,
+ "Failed to add field to doc");
+ cpix_ClearError(doc);
+ cpix_Document_destroy(doc);
+ cpix_Field_release(&filterIdField);
+ // at this point reader is owned by field already
+ return;
+ }
+
+ cpix_IdxDb_add(idxDb(),
+ doc,
+ analyzer);
+
+ if (cpix_Failed(idxDb()))
+ {
+ cpix_Error_report(idxDb()->err_,
+ report,
+ sizeof(report)/sizeof(wchar_t));
+ ITK_EXPECT(testMgr,
+ false,
+ "Failed to index document %S: %S\n",
+ wpath,
+ report);
+ cpix_ClearError(idxDb());
+ }
+ else
+ {
+ wpath[0] = '!';
+ ITK_MSG(testMgr,
+ "Indexed file: %S",
+ wpath);
+ }
+
+ cpix_Document_destroy(doc);
+}
+
+
+cpix_FieldDesc FileSchema[] = {
+ {
+ LCPIX_FILTERID_FIELD, // name_
+ cpix_STORE_YES | cpix_INDEX_NO, // cfg_
+ }
+};
+
+
+const char * FileIdxUtil::qualBaseAppClass() const
+{
+ return FILE_QBASEAPPCLASS;
+}
+
+
+const char * FileIdxUtil::idxDbPath() const
+{
+ return NULL;
+}
+
+
+SchemaId FileIdxUtil::addSchema() throw (Itk::PanicExc)
+{
+ return cpix_IdxDb_addSchema(idxDb(),
+ FileSchema,
+ sizeof(FileSchema)/sizeof(cpix_FieldDesc));
+}
+
+
+std::wstring FileIdxUtil::getIdStr(cpix_Document * doc,
+ Itk::TestMgr * testMgr)
+{
+ const wchar_t
+ * value = cpix_Document_getFieldValue(doc,
+ LCPIX_DOCUID_FIELD);
+ ITK_EXPECT(testMgr, value != NULL, "DOCUID field not found");
+
+ std::wstring
+ rv(value);
+
+ rv[0] = '!';
+
+ return rv;
+}
+
+
+
+VolumeFileIdxUtil::VolumeFileIdxUtil(const MVFTest * mvfTest)
+ : mvfTest_(mvfTest)
+{
+ ;
+}
+
+
+VolumeFileIdxUtil::~VolumeFileIdxUtil() throw ()
+{
+ ;
+}
+
+
+const char * VolumeFileIdxUtil::qualBaseAppClass() const
+{
+ return mvfTest_->qualifiedBaseAppClass_;
+}
+
+
+const char * VolumeFileIdxUtil::idxDbPath() const
+{
+ return mvfTest_->idxDbPath_;
+}
+