diff -r 000000000000 -r 1f04cf54edd8 symhelp/helpmodel/tsrc/TSearch.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/symhelp/helpmodel/tsrc/TSearch.cpp Tue Jan 26 15:15:23 2010 +0200 @@ -0,0 +1,717 @@ +// Copyright (c) 1999-2009 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: +// Test Help Model module to check the PlatSec search order. +// This test uses and additional drive typically F: It should be mapped in the epoc.ini file. +// Mapping is achieved for example thus: _EPOC_DRIVE_F c:\temp +// +// + +// System includes +#include +#include + + +#include +#include +#include +#include + +// User includes +#include +#include "HLPMODEL.H" +#include +#include "SearchOrderTest.h" + +// Globals +static TInt64 TheSeed; +static RFs TheFs; +static RTest TheTest(_L("TSearch - Test Help Model Searching")); +static CTrapCleanup* TheTrapCleanup; +static CActiveScheduler* TheScheduler; + +// Constants +const TInt KTestCleanupStack=0x20; + + +// Panic enum +enum THlpPanic + { + EHlpPanicNoBossFile, + EHlpPanicLast + }; + + +// +// ---------> Global functions +// + +static void Panic(THlpPanic aPanic) + { + _LIT(KHlpPanicCategory, "TSearch"); + User::Panic(KHlpPanicCategory, aPanic); + } + + +static TInt Rand(const TInt aLow, const TInt aHigh) +// +// Generate a random number based upon a seed and a range +// + { + TReal initialRand = (Math::FRand(TheSeed) * (aHigh - aLow)); + TInt32 rand; + + // Round to 0 decimal places, ie. the nearest whole numer + Math::Round(initialRand, initialRand, 0); + Math::Int(rand, initialRand); + + //aSeed = seed; + return (aLow + rand); + } + + + +// +// ---------> CHlpSearchTest (header) +// +class CHlpSearchTest: public CBase, public MHlpModelObserver + { +public: // CONSTRUCT / DESTRUCT + static void TestHelpModelLD(TBool aOomTesting = EFalse); + ~CHlpSearchTest(); + +private: + CHlpSearchTest(); + +public: // NEW + void TestL(TBool aOomTesting = EFalse); + +public: // FROM MHlpModelObserver + void HandleModelEventL(TInt aEvent); + +private: // TESTING METHODS + void BasicCreateAndCloseL(); + void IndexListL(TBool aOomTesting = EFalse); + void CategoryListL(TBool aOomTesting = EFalse); + void TopicListForCategoryL(); + void ContextSearchL(TBool aOomTesting = EFalse); + void IndexSearchL(); + void TextSearchL(TBool aOomTesting = EFalse); + void CategoryUidSearchL(TBool aOomTesting = EFalse); + +private: + void Reset(); + TBool FileExists(const TDesC& aFileName); + CDesCArray* CategoryListLC(); + +private: // MEMBER DATA + TInt iResponseCount; + TInt iLastHelpModelResponse; + TInt iSearchProgressCount; + TInt iSearchCancelValue; + TBool iIsAsynchronous; + TBool iSchedulerStarted; + CHlpModel* iModel; + }; + + + + + + +// +// ---------> CHlpSearchTest (source) +// + +CHlpSearchTest::CHlpSearchTest() + { + } + + +CHlpSearchTest::~CHlpSearchTest() + { + delete iModel; + } + + +void CHlpSearchTest::TestHelpModelLD(TBool aOomTesting) + { + CHlpSearchTest* self = new(ELeave) CHlpSearchTest(); + CleanupStack::PushL(self); + self->TestL(aOomTesting); + CleanupStack::PopAndDestroy(); + } + + +// +// +// + + +void CHlpSearchTest::TestL(TBool aOomTesting) + { + iModel = CHlpModel::NewL(TheFs, this); + iModel->OpenL(); + + + BasicCreateAndCloseL(); + IndexListL(aOomTesting); + CategoryListL(aOomTesting); + TopicListForCategoryL(); + ContextSearchL(aOomTesting); + TextSearchL(aOomTesting); + CategoryUidSearchL(aOomTesting); + } + + +// +// +// + +void CHlpSearchTest::BasicCreateAndCloseL() + { + TheTest.Console()->ClearScreen(); + TheTest.Printf(_L("Testing basic open, close and destruction\n")); + + __UHEAP_MARK; + CHlpModel::NewLC(TheFs, NULL); + CleanupStack::PopAndDestroy(); // model + __UHEAP_MARKEND; + + __UHEAP_MARK; + CHlpModel* model = CHlpModel::NewLC(TheFs, NULL); + model->OpenL(); + CleanupStack::PopAndDestroy(); // model + __UHEAP_MARKEND; + } + +void CHlpSearchTest::IndexListL(TBool aOomTesting) + { + TheTest.Console()->ClearScreen(); + TheTest.Printf(_L("Testing index listing\n")); + Reset(); + + iModel->SearchL(EIndexList); + + if(!aOomTesting) + { + TheTest(iLastHelpModelResponse == EIndexListAvailable); + } + TheTest(iResponseCount == 1); + + // Load the complete list of entries for all help files + CHlpList* list = CHlpList::NewLC(); + iModel->LoadListL(list); + TheTest.Printf(_L("\tComplete index listing for all help files...")); + TInt i=0; + for(i=0; iMdcaCount(); i++) + { + CHlpItem* item = list->Item(i); + TPtrC pItem(item->Title()); + TheTest.Printf(_L("\nIndex list [0x%08x][indexId=%d]: %S "), item->HelpFileUid(), item->Id(), &pItem); + } + TheTest.Printf(_L("\n")); + + // Next select an item from the complete list (at random) + + if(list->MdcaCount()!=0) + { + CHlpItem* item = list->Item(Rand(0, list->MdcaCount()-1)); + + // Save these for later... + TUint helpFileUid = item->HelpFileUid().iUid; + TUint indexId = item->Id(); + + // Next perform a topic search based on this item + iModel->IndexSearchL(*item); + TheTest(iLastHelpModelResponse == EIndexSearchListAvailable); + CleanupStack::PopAndDestroy(); // list + + // Next load the list of topics which match the index id + list = CHlpList::NewLC(); + iModel->LoadListL(list); + TheTest.Printf(_L("\tTopic listing in help file 0x%08x, whose index id = %d"), helpFileUid, indexId); + for(i=0; iMdcaCount(); i++) + { + CHlpItem* item = list->Item(i); + TPtrC pItem(item->Title()); + TheTest.Printf(_L("\nTopic [Uid: 0x%08x]: %S "), item->HelpFileUid(), &pItem); + } + } + TheTest.Printf(_L("\n")); + + CleanupStack::PopAndDestroy(); // list + } + + +void CHlpSearchTest::CategoryListL(TBool aOomTesting) + { + TheTest.Console()->ClearScreen(); + TheTest.Printf(_L("Testing category listing\n")); + + Reset(); + iModel->SearchL(ECategoryList); + if(!aOomTesting) + { + TheTest(iLastHelpModelResponse == ECategoryListAvailable); + } + + // Display the index listing... + CHlpList* list = CHlpList::NewLC(); + iModel->LoadListL(list); + + for(TInt i=0; iMdcaCount(); i++) + { + TPtrC pItem(list->MdcaPoint(i)); + TheTest.Printf(_L("\nCategory item %d: %S"), i, &pItem); + } + TheTest.Printf(_L("\n")); + CleanupStack::PopAndDestroy(); // list + } + + +void CHlpSearchTest::TopicListForCategoryL() + { + TheTest.Printf(_L("Testing topic listing\n")); + Reset(); + + // First get a category listing, then get the list of topics + // for each specified category. + CDesCArrayFlat* array = STATIC_CAST(CDesCArrayFlat*, CategoryListLC()); + const TInt count = array->Count(); + for(TInt i=0; iMdcaPoint(i); + TheTest.Printf(_L("\nTopics for Category %S\n"), &pItem); + + // Calling this will result in the topics for this category + // being printed out in the mixin handler + iModel->SearchL(ETopicListForCategory, pItem); + } + CleanupStack::PopAndDestroy(); // array + } + + +void CHlpSearchTest::ContextSearchL(TBool aOomTesting) + { + TheTest.Printf(_L("Testing context searching\n")); + Reset(); + + // Context search for an item we know exists + _LIT(KContext1, "This_is_a_multi_word_context2"); + + TUid uid = { 16777216 }; + TCoeHelpContext coeSearchContext(uid, KContext1); + iModel->ContextSearchL(coeSearchContext); + if(!aOomTesting) + { + TheTest(iLastHelpModelResponse == ETopicAvailable); + } + + + // Context search for an item we know doesn't exist + _LIT(KContext2, "ABCDEFG"); + + TUid uid2 = { 00000000 }; + TCoeHelpContext coeSearchContext2(uid2, KContext2); + iModel->ContextSearchL(coeSearchContext2); + TheTest(iLastHelpModelResponse == ETopicNotFound); + } + + +void CHlpSearchTest::TextSearchL(TBool aOomTesting) + { + if(aOomTesting) + return; + + _LIT(KFullTextShouldNotBeFound, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); + TheTest.Printf(_L("Testing text searching (when item shouldn't be found)\n")); + + Reset(); + iSchedulerStarted = EFalse; + iIsAsynchronous = ETrue; + iModel->SearchL(EFullTextSearch, KFullTextShouldNotBeFound); + iSchedulerStarted = ETrue; + CActiveScheduler::Start(); + TheTest(iLastHelpModelResponse == ESearchListNoneFound); + + _LIT(KFullTextShouldBeFound, "boss"); + TheTest.Printf(_L("Testing text searching (when item should be found)\n")); + + Reset(); + iSchedulerStarted = EFalse; + iIsAsynchronous = ETrue; + iModel->SearchL(EFullTextSearch, KFullTextShouldBeFound); + iSchedulerStarted = ETrue; + CActiveScheduler::Start(); + TheTest(iLastHelpModelResponse == ESearchListAvailable); + + TheTest.Printf(_L("\tTesting asynch cancel function\n")); + TInt searchCancelValue = Max(1, iSearchProgressCount / 2); // stop half way through + + Reset(); + iSearchCancelValue = searchCancelValue; + iSchedulerStarted = EFalse; + iIsAsynchronous = ETrue; + iModel->SearchL(EFullTextSearch, KFullTextShouldBeFound); + iSchedulerStarted = ETrue; + CActiveScheduler::Start(); + } + + +void CHlpSearchTest::CategoryUidSearchL(TBool aOomTesting) + { + TheTest.Console()->ClearScreen(); + TheTest.Printf(_L("Testing category uid searching - *requires boss help file*\n")); + + + if ((!FileExists(_L("C:\\Resource\\Help\\Boss-1.hlp"))) && (!FileExists(_L("Z:\\Resource\\Help\\Boss-1.hlp")))) + Panic(EHlpPanicNoBossFile); + + + Reset(); + iModel->CategoryUIDSearchL(TUid::Uid(16777216)); // hard coded category uid from Boss1.hlp + if(!aOomTesting) + { + TheTest(iLastHelpModelResponse == ETopicListAvailable); + } + TheTest(iResponseCount == 1); + + // Display the index listing... + CHlpList* list = CHlpList::NewLC(); + iModel->LoadListL(list); + + for(TInt i=0; iMdcaCount(); i++) + { + TPtrC pItem(list->MdcaPoint(i)); + TheTest.Printf(_L("\nCategory item %d: %S"), i, &pItem); + } + CleanupStack::PopAndDestroy(); // list + TheTest.Printf(_L("\n")); + + // Test for a category that we know doesn't exist + Reset(); + iModel->CategoryUIDSearchL(KNullUid); + TheTest(iLastHelpModelResponse == ETopicListNoneFound); + TheTest(iResponseCount == 1); + } + + +// +// +// + + +void CHlpSearchTest::Reset() + { + iResponseCount = 0; + iLastHelpModelResponse = KErrGeneral; + iIsAsynchronous = EFalse; + iSearchProgressCount = 0; + iSearchCancelValue = KErrNone-1; // Anything less that KErrNone + } + +TBool CHlpSearchTest::FileExists(const TDesC& aFileName) + { + TEntry entry; + TInt error = TheFs.Entry(aFileName, entry); + if (error == KErrInUse) + return ETrue; + if (error < KErrNone) + return EFalse; + return (!entry.IsDir()); + } + +CDesCArray* CHlpSearchTest::CategoryListLC() + { + // Get and print the category listing + CDesCArrayFlat* array = new(ELeave) CDesCArrayFlat(5); + CleanupStack::PushL(array); + iModel->CategoryListL(array); + return array; + } + + +// +// +// + + +void CHlpSearchTest::HandleModelEventL(TInt aEvent) + { + iResponseCount++; + iLastHelpModelResponse = aEvent; + + // If this test included an asynch search, and there was a cancel value set + // then cancel the asynch searcher + if (++iSearchProgressCount == iSearchCancelValue && iIsAsynchronous) + { + // Reset this otherwise we'll get stuck in a loop + iSearchCancelValue = KErrNone-1; + + // Only works for full test searching as this is the only search type + // which uses an active object, and even then it doesn't use them properly. + TheTest(iModel->CancelSearch() == KErrNone); + } + + switch (aEvent) + { + case ESearchListAvailable: // text searches + TheTest.Printf(_L("\n\tESearchListAvailable\n")); + break; + + case ECategoryListAvailable: + { + TheTest.Printf(_L("\n\tECategoryListAvailable\n")); + + // Get and print the category listing + CDesCArrayFlat* array = STATIC_CAST(CDesCArrayFlat*, CategoryListLC()); + const TInt count = array->Count(); + for(TInt i=0; iMdcaPoint(i); + TheTest.Printf(_L("Category %d: %S\n"), i, &pItem); + } + CleanupStack::PopAndDestroy(); // array + break; + } + case ECategoryListNoneFound: + TheTest.Printf(_L("\n\tECategoryListNoneFound\n")); + break; + + + case ETopicListAvailable: // category expansion + { + TheTest.Printf(_L("\n\tETopicListAvailable\n")); + CHlpList* list = CHlpList::NewLC(); + iModel->LoadListL(list); + TInt count = list->MdcaCount(); + for(TInt i=0; iItem(i); + TPtrC pTitle(*item->iTitle); + TheTest.Printf(_L("Topic %d: %S (id = %d)\n"), i, &pTitle, item->iId); + } + CleanupStack::PopAndDestroy(); // list + break; + } + case ETopicListNoneFound: + TheTest.Printf(_L("\n\tETopicListNoneFound\n")); + break; + + + case ETopicAvailable: // topic text + TheTest.Printf(_L("\n\tETopicAvailable\n")); + break; + case ETopicNotFound: + TheTest.Printf(_L("\n\tETopicNotFound\n")); + break; + + + case EIndexListAvailable: // index list + TheTest.Printf(_L("\n\tEIndexListAvailable\n")); + break; + case EIndexListNoneFound: + TheTest.Printf(_L("\n\tEIndexListNoneFound\n")); + break; + case EIndexSearchListAvailable: // topic list from index phrase + TheTest.Printf(_L("\n\tEIndexSearchListAvailable\n")); + break; + case EIndexSearchListNoneFound: + TheTest.Printf(_L("\n\tEIndexSearchListNoneFound\n")); + break; + + + case EHlpSearchCancelled: + TheTest.Printf(_L("")); + break; + case EModelSearchInProgress: + TheTest.Printf(_L("...")); + return; + case ESearchListNoneFound: + TheTest.Printf(_L("\n\tESearchListNoneFound\n")); + break; + } + + if (iIsAsynchronous && iSchedulerStarted) + CActiveScheduler::Stop(); + } + +/** + doSearchOrderTest + + All help files used in this part of the test use the Category UID of 0x01007000 + Within each source RTF file the Category is defined as the drive name. + Hence the File copied to c:\resource\help has the Category "Drive C:" + There are 3 help files used in this test: + PlatSecSearchTestC.hlp - initially resides in z:\System\Programs\THlpmodel\ + PlatSecSearchTestF.hlp - initially resides in z:\System\Programs\THlpmodel\ + PlatSecSearchTest.hlp - (with Category "Drive Z:") resides in z:\Resoruce\Help + The exports are specified in the Hlpmodel BLD.INF file. + + As part of the building process the help files are exported to the + corresponding directories. + + Thus initially only PlatSecSearchTest.hlp with be visible presenting + the Category "Drive Z:". As the test progresses so the 2 remaining files are + copied (with a change in name) from z:\System\Programs\THlpmodel\ to their corresponding drive. + Thus PlatSecSearchTestC.hlp becomes PlatSecSearchTest.hlp in c:\Resource\Help + and PlatSecSearchTestF.hlp becomes PlatSecSearchTest.hlp in f:\Resource\Help + + Given the search order, the higher drive letter takes presidence (however z: is last), + so when there are is a file called PlatSecSearchTest.hlp on z:, c: and f: only f: + will be seen. + + Note: That the test looks for a drive of type EMediaHardDisk: on Lubbock this will be F: + on the H2 it is likely to be E: this is managed within CSearchOrderTest. +*/ + + + +static void doSearchOrderTestL() + { + __UHEAP_MARK; + TheTest.Printf(_L("-------------------------------------------\n")); + TheTest.Printf(_L(" Testing PlatSec drive search Order.\n")); + TheTest.Printf(_L("-------------------------------------------\n")); + + // Initialise the array of mapped drives. + CSearchOrderTest* sort = CSearchOrderTest::NewL(TheTest); + CleanupStack::PushL( sort ); + + TheTest.Next(_L("Test category listing")); + + CHlpModel* model = CHlpModel::NewLC(TheFs, NULL); + + CDesCArray* catList = new(ELeave) CDesCArrayFlat(2); + CleanupStack::PushL(catList); + + // Iterate around Drive Loop + TBool found = EFalse; + for( TInt operation =CSearchOrderTest::EInitial_DeleteAll; + operation<=CSearchOrderTest::EFinal_DeleteAll; + operation++) + { + sort->MoveHelpFileL( operation ); + model->OpenL(); + // Get the new gategory list, resulting from the repositioned file. + model->CategoryListL(catList); + // Close help model to release file handles. + model->CloseL(); + // Check listed categories given the current index. + found = sort->CheckCategoryListL( operation, catList ); + if( found ) + { + TheTest.Printf(_L("The Correct Category was found.")); + } + TheTest(found); + // Remove the old contents, otherwise new + // categories are simply added. + catList->Reset(); + } + CleanupStack::PopAndDestroy( catList ); + CleanupStack::PopAndDestroy( model ); + CleanupStack::PopAndDestroy( sort ); + __UHEAP_MARKEND; + } + +static void PerformOOMTestL() + { + TInt ret=KErrNoMemory; + TInt failAt=0; + while (ret!=KErrNone) + { + failAt++; + __UHEAP_SETFAIL(RHeap::EDeterministic,failAt); + __UHEAP_MARK; + TRAP(ret, CHlpSearchTest::TestHelpModelLD(ETrue)); + if (ret!=KErrNone) + { + __UHEAP_MARKEND; + } + __UHEAP_RESET; + TheTest(ret==KErrNoMemory||ret==KErrNone); + } + } + +static void setupFileServerAndSchedulerL() +// +// Initialise the cleanup stack. +// + { + TTime time; + time.HomeTime(); + TheSeed = time.Int64(); + + TheTest(TheFs.Connect() == KErrNone); + TheScheduler = new (ELeave) CActiveScheduler; + CActiveScheduler::Install(TheScheduler); + } + + +static void setupCleanup() +// +// Initialise the cleanup stack. +// + { + TheTrapCleanup = CTrapCleanup::New(); + TheTest(TheTrapCleanup!=NULL); + TRAPD(r, + { + for (TInt i=KTestCleanupStack;i>0;i--) + CleanupStack::PushL((TAny*) 0); + CleanupStack::Pop(KTestCleanupStack); + }); + TheTest(r==KErrNone); + } + +/** +@SYMTestCaseID PIM-TSEARCH-0001 +*/ +GLDEF_C TInt E32Main() +// +// Test Help Model API +// + { + __UHEAP_MARK; + + TheTest.Title(); + TheTest.Start(_L("@SYMTestCaseID PIM-TSEARCH-0001")); + setupCleanup(); + + __UHEAP_MARK; + TRAPD(r, + setupFileServerAndSchedulerL(); + CHlpSearchTest::TestHelpModelLD(); + ); + + TheTest(r==KErrNone); + __UHEAP_MARKEND; + + TRAP(r, PerformOOMTestL()); + TheTest(r==KErrNone); + + // PlatSec search order test. + TRAP(r, doSearchOrderTestL()); + TheTest(r==KErrNone); + + + delete TheScheduler; + delete TheTrapCleanup; + TheFs.Close(); + TheTest.End(); + TheTest.Close(); + + __UHEAP_MARKEND; + return KErrNone; + }