searchengine/cpix/tsrc/cpixunittest/src/destructivetests.cpp
changeset 0 671dee74050a
child 3 ae3f1779f6da
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 "testutils.h"
       
    19 #include "testcorpus.h"
       
    20 #include "config.h"
       
    21 #include "itk.h"
       
    22 #include "setupsentry.h"
       
    23 
       
    24 #include <iostream>
       
    25 
       
    26 #include "cpixsearch.h"
       
    27 
       
    28 // Disable test cases, which prevent running other cases
       
    29 #define DISABLE_CRASHING_TEST_CASES
       
    30 
       
    31 class DestructiveTests : public Itk::ITestContext
       
    32 {
       
    33 private: // data
       
    34 	
       
    35     SmsIdxUtil* idxUtil_; 
       
    36     LineTestCorpusRef testCorpus_; 
       
    37 		
       
    38     cpix_Analyzer* analyzer_;
       
    39     cpix_QueryParser* uidQueryParser_;
       
    40     cpix_QueryParser* contentQueryParser_;
       
    41     cpix_IdxSearcher * searcher_;
       
    42 		
       
    43 public: // Constructors & destructors
       
    44 	
       
    45     DestructiveTests() 
       
    46         : idxUtil_(NULL),
       
    47           testCorpus_(DEFAULT_TEST_CORPUS_PATH),
       
    48           analyzer_(NULL),
       
    49           uidQueryParser_(NULL),
       
    50           contentQueryParser_(NULL),
       
    51           searcher_(NULL)
       
    52     {
       
    53         ;
       
    54     }
       
    55 
       
    56 
       
    57     ~DestructiveTests() 
       
    58     {
       
    59         cleanup();
       
    60     }
       
    61 		
       
    62 
       
    63     void setup() throw (Itk::PanicExc) 
       
    64     {
       
    65         SetupSentry
       
    66             ss(*this);
       
    67 
       
    68         cpix_Result
       
    69             result;
       
    70 
       
    71         // cpix_setLogLevel(CPIX_LL_DEBUG);
       
    72 
       
    73         cpix_IdxDb_dbgScrapAll(&result);
       
    74 
       
    75         if (cpix_Failed(&result))
       
    76             {
       
    77                 ITK_PANIC("Could not scrap all");
       
    78             }
       
    79 
       
    80         idxUtil_ = new SmsIdxUtil; 
       
    81         idxUtil_->init( true );
       
    82 
       
    83         analyzer_ = cpix_CreateSimpleAnalyzer(&result);
       
    84         if ( !analyzer_ )
       
    85             {
       
    86                 ITK_PANIC("Analyzer could not be created");
       
    87             }
       
    88         
       
    89         uidQueryParser_ = cpix_QueryParser_create( &result,
       
    90                                                                    LCPIX_DOCUID_FIELD, 
       
    91                                                                    analyzer_ );
       
    92         if ( !( uidQueryParser_ ) )
       
    93             {
       
    94                 ITK_PANIC("Query parser could not be created");
       
    95             }
       
    96 	
       
    97         contentQueryParser_ = cpix_QueryParser_create( &result,
       
    98                                                                        LBODY_FIELD, 
       
    99                                                                        analyzer_ );
       
   100         if ( !( contentQueryParser_ ) )
       
   101             {
       
   102                 ITK_PANIC("Query parser could not be created");
       
   103             }
       
   104 
       
   105         ss.setupComplete();
       
   106     }
       
   107 		
       
   108 
       
   109 
       
   110     void tearDown() throw () 
       
   111     {
       
   112         cleanup();
       
   113 
       
   114         // cpix_setLogLevel(CPIX_LL_TRACE);
       
   115     }
       
   116 		
       
   117 public: // Test cases
       
   118 
       
   119     void cleanup()
       
   120     {
       
   121         cpix_Analyzer_destroy( analyzer_ ); 
       
   122         analyzer_ = NULL;
       
   123         cpix_QueryParser_destroy( uidQueryParser_ ); 
       
   124         uidQueryParser_ = NULL;
       
   125         cpix_QueryParser_destroy( contentQueryParser_ ); 
       
   126         contentQueryParser_ = NULL;
       
   127         delete idxUtil_;
       
   128         idxUtil_ = NULL;
       
   129         cpix_IdxSearcher_releaseDb(searcher_);
       
   130         searcher_ = NULL;
       
   131     }
       
   132 		
       
   133     void testWritingWhenHitIterating(Itk::TestMgr* testMgr) {
       
   134         testWritingWhenHitIterating(testMgr,
       
   135                                     idxUtil_->idxDb(),
       
   136                                     &cpix_IdxDb_search,
       
   137                                     3);
       
   138     }
       
   139 
       
   140 
       
   141     void testWritingWhenHitIterating2(Itk::TestMgr* testMgr) {
       
   142         testWritingWhenHitIterating(testMgr,
       
   143                                     searcher(testMgr),
       
   144                                     &cpix_IdxSearcher_search,
       
   145                                     3);
       
   146     }
       
   147 
       
   148     void testInvalidation(Itk::TestMgr* testMgr) 
       
   149     {
       
   150         for (int i = 0; i < 25; i++) 
       
   151             {
       
   152                 idxUtil_->indexSms( i, 
       
   153                                     testCorpus_.item(i).c_str(), 
       
   154                                     analyzer_, 
       
   155                                     testMgr, 
       
   156                                     false ); 
       
   157             }
       
   158         idxUtil_->flush();
       
   159 
       
   160         cpix_Query* query = cpix_QueryParser_parse( contentQueryParser_, L"ok" );
       
   161 	
       
   162         ITK_ASSERT( testMgr, query, "Query parsing failed" );
       
   163 
       
   164         cpix_Hits *hits =
       
   165             cpix_IdxDb_search(idxUtil_->idxDb(), query );
       
   166 		
       
   167         if ( cpix_Failed( idxUtil_->idxDb() ) ) {
       
   168             cpix_Query_destroy( query );
       
   169             ITK_PANIC( "Search failed" );
       
   170         }
       
   171         printf("Accessing hits before closing... ");
       
   172 
       
   173         cpix_Hits_length( hits ); 
       
   174         ITK_ASSERT( testMgr, cpix_Succeeded( hits  ), "Accessing hit length failed" ); 
       
   175         printf("OK. Hits could be accessed.\n");
       
   176 
       
   177         /* OBS
       
   178         // cleanup
       
   179         idxUtil_->close(); 
       
   180         */
       
   181 
       
   182 
       
   183         for (int i = 0; i < 5; i++) 
       
   184             {
       
   185                 idxUtil_->indexSms( i, 
       
   186                                     testCorpus_.item(i).c_str(), 
       
   187                                     analyzer_, 
       
   188                                     testMgr, 
       
   189                                     false ); 
       
   190             }
       
   191         cpix_IdxDb_flush(idxUtil_->idxDb());
       
   192         ITK_EXPECT(testMgr,
       
   193                    cpix_Succeeded(idxUtil_->idxDb()),
       
   194                    "Flushing failed");
       
   195         
       
   196 
       
   197         cpix_IdxSearcher_releaseDb(searcher_);
       
   198         searcher_ = NULL;
       
   199         idxUtil_->close();
       
   200 
       
   201         // Confirm no crash and that access fails
       
   202 
       
   203         printf("Accessing hits after closing... \n");
       
   204         cpix_Document
       
   205             doc;
       
   206 
       
   207         printf("doc #0: ");
       
   208         cpix_Hits_doc(hits,
       
   209                       0,
       
   210                       &doc);
       
   211         ITK_EXPECT( testMgr, 
       
   212                     cpix_Succeeded( hits ), 
       
   213                     "Accessing hit(0) should succeeded for closed database (hits still holds a reference to its originator)." ); 
       
   214 
       
   215         if (cpix_Failed(hits))
       
   216             {
       
   217                 wchar_t
       
   218                     buf[256];
       
   219                 cpix_Error_report(hits->err_,
       
   220                                   buf,
       
   221                                   sizeof(buf) / sizeof(wchar_t));
       
   222                 printf("%S\n", buf);
       
   223                 cpix_ClearError(hits);
       
   224             }
       
   225 
       
   226         printf("\ndoc #20: ");
       
   227         cpix_Hits_doc(hits,
       
   228                       20,
       
   229                       &doc);
       
   230         ITK_EXPECT( testMgr, 
       
   231                     cpix_Failed( hits ), 
       
   232                     "Accessing hit(20) should NOT succeeded for closed database (hits still holds a reference to its originator)." ); 
       
   233 
       
   234         if (cpix_Failed(hits))
       
   235             {
       
   236                 wchar_t
       
   237                     buf[256];
       
   238                 cpix_Error_report(hits->err_,
       
   239                                   buf,
       
   240                                   sizeof(buf) / sizeof(wchar_t));
       
   241                 printf("%S\n", buf);
       
   242                 cpix_ClearError(hits);
       
   243             }
       
   244         
       
   245         cpix_Hits_destroy( hits );
       
   246         cpix_Query_destroy( query );
       
   247     }
       
   248 
       
   249 
       
   250     /**
       
   251      * The purpose of this test is to test the stack unwinding problem, 
       
   252      * which occurs e.g. if we provide bad schema and the idxdb will react 
       
   253      * by throwing an exception.
       
   254      */
       
   255     void testStackunwinding(Itk::TestMgr* testMgr) 
       
   256     {
       
   257         SchemaId wrongSchema = idxUtil_->schemaId();
       
   258         cpix_Result
       
   259             result;
       
   260 		
       
   261         delete idxUtil_;
       
   262         idxUtil_ = NULL;
       
   263 		
       
   264         cpix_IdxDb
       
   265             * idxDb = cpix_IdxDb_openDb(&result,
       
   266                                         SMS_QBASEAPPCLASS,
       
   267                                         cpix_IDX_OPEN);
       
   268         // Open index without redefining schema
       
   269         
       
   270         if (cpix_Failed(&result))
       
   271             {
       
   272                 ITK_PANIC("Index could not be opened");
       
   273             }
       
   274 
       
   275         // Try to index things
       
   276         for (int i = 0; i < 5; i++) 
       
   277             {
       
   278                 std::wstring id = GetItemId( i );
       
   279                 std::wstring content = testCorpus_.item( i );
       
   280 
       
   281                 const wchar_t
       
   282                     * fields[4];
       
   283                 fields[0] = L"+3585553412"; // to
       
   284                 fields[1] = L"+3585559078"; // from
       
   285                 fields[2] = L"inbox"; // folder
       
   286                 fields[3] = content.c_str();// body
       
   287 
       
   288 					
       
   289                 cpix_IdxDb_add2( idxDb,
       
   290                                  wrongSchema,
       
   291                                  id.c_str(),
       
   292                                  // OBS DEFAULT_APPTYPE,
       
   293                                  SMSAPPCLASS,
       
   294                                  content.c_str(),
       
   295                                  NULL,
       
   296                                  fields,
       
   297                                  analyzer_ );
       
   298 
       
   299                 bool
       
   300                     succeeded = cpix_Succeeded(idxDb);
       
   301 
       
   302                 ITK_ASSERT( testMgr, !succeeded, "Schema is persistent?" ); 
       
   303             }
       
   304 			
       
   305         cpix_IdxDb_releaseDb(idxDb);
       
   306         idxDb = NULL; 
       
   307 			
       
   308         idxUtil_ = new SmsIdxUtil; 
       
   309         idxUtil_->init( true );
       
   310 			
       
   311     }
       
   312 
       
   313 
       
   314 private:
       
   315     template<typename IDX>
       
   316     void testWritingWhenHitIterating(Itk::TestMgr * testMgr,
       
   317                                      IDX          * idx,
       
   318                                      cpix_Hits * (* searcher)(IDX*,cpix_Query*),
       
   319                                      int32_t       matches) 
       
   320     {
       
   321         wprintf(L"Testing writing to index, while hit object is continuosly read.\n");
       
   322 	
       
   323         // Index 
       
   324         for (int i = 0; i < 25; i++) {
       
   325             idxUtil_->indexSms( i, 
       
   326                                 testCorpus_.item(i).c_str(), 
       
   327                                 analyzer_, 
       
   328                                 testMgr, 
       
   329                                 false ); 
       
   330         }
       
   331         idxUtil_->flush();
       
   332 	
       
   333         printf("25 items indexed.\n");
       
   334 	
       
   335         cpix_Query* query = cpix_QueryParser_parse( contentQueryParser_, L"ok" );
       
   336 			
       
   337         if ( query != NULL ) {
       
   338             cpix_Hits *hits =
       
   339                 (*searcher)(idx, query );
       
   340 		
       
   341             if ( hits )
       
   342                 {
       
   343                     // We know that 25 first message contain this many 'ok's. 
       
   344                     ITK_EXPECT( testMgr, cpix_Hits_length( hits ) == matches,
       
   345                                 "There should be %d matches instead of %d",
       
   346                                 matches,
       
   347                                 cpix_Hits_length(hits));
       
   348                     int length = 0; 
       
   349 					 
       
   350                     printf("Hits after indexing: \n");
       
   351                     idxUtil_->printHits( hits, testMgr ); 
       
   352 										
       
   353                     // Should this also crash? By the way, this is one of the document results
       
   354                     idxUtil_->indexSms( 25, 
       
   355                                         testCorpus_.item(25).c_str(), 
       
   356                                         analyzer_, 
       
   357                                         testMgr, 
       
   358                                         false ); 
       
   359 					 
       
   360                     ITK_EXPECT( testMgr, cpix_Succeeded( idx ), "Adding 25th item failed" ); 
       
   361 	
       
   362                     printf("1 item indexed. \n");
       
   363 	
       
   364                     cpix_Hits_length( hits );
       
   365                     ITK_EXPECT( testMgr, cpix_Succeeded( hits  ), "Accessing hit of index 1 failed" ); 
       
   366 					
       
   367                     printf("Hits after adding 1 item.\n");
       
   368                     idxUtil_->printHits( hits, testMgr ); 
       
   369 								
       
   370                     cpix_IdxDb_deleteDocuments(idxUtil_->idxDb(), GetItemId( 15 ).c_str() );
       
   371                     ITK_EXPECT( testMgr, cpix_Succeeded( idxUtil_->idxDb() ), "Deleting document 15 failed" ); 
       
   372 					
       
   373                     printf("Line 16 deleted.\n");
       
   374 	
       
   375                     printf("Hits after deletion: \n");
       
   376                     idxUtil_->printHits( hits, testMgr ); 
       
   377 					
       
   378                     cpix_IdxDb_flush(idxUtil_->idxDb() );
       
   379                     ITK_EXPECT( testMgr, cpix_Succeeded( idxUtil_->idxDb() ), "Flushing failed" );
       
   380                     printf("Flushed.\n");
       
   381 					
       
   382                     printf("Hits after flush:\n");
       
   383                     idxUtil_->printHits( hits, testMgr, true ); 
       
   384 					 
       
   385                     cpix_IdxDb_deleteDocuments(idxUtil_->idxDb(), GetItemId( 14 ).c_str() );
       
   386                     ITK_EXPECT( testMgr, cpix_Succeeded( idxUtil_->idxDb() ), "Deleting document 14 failed" ); 
       
   387 	
       
   388                     printf("Line 15 deleted.\n");
       
   389                     printf("Hits after deletion:\n");
       
   390                     idxUtil_->printHits( hits, testMgr ); 
       
   391 	
       
   392                     cpix_IdxDb_deleteDocuments(idxUtil_->idxDb(), GetItemId( 9 ).c_str() );
       
   393                     ITK_EXPECT( testMgr, cpix_Succeeded( idxUtil_->idxDb() ), "Deleting document 9 failed" ); 
       
   394 	
       
   395                     printf("Line 10 deleted.\n");
       
   396                     printf("Hits after deletion:\n");
       
   397                     idxUtil_->printHits( hits, testMgr ); 
       
   398 	
       
   399                     cpix_IdxDb_flush(idxUtil_->idxDb() );
       
   400                     ITK_EXPECT( testMgr, cpix_Succeeded( idxUtil_->idxDb() ), "Flushing failed" );
       
   401                     printf("Flushed.\n");
       
   402 					
       
   403                     printf("Hits after flush:\n");
       
   404                     idxUtil_->printHits( hits, testMgr, true ); 
       
   405 					 
       
   406                     ITK_EXPECT( testMgr, cpix_Succeeded( hits  ), "Accessing hit length failed" ); 
       
   407                     ITK_EXPECT( testMgr, length == 0, "The items were not deleted." ); 
       
   408 					
       
   409                     cpix_Hits_destroy( hits );
       
   410                 }
       
   411             else 
       
   412                 {
       
   413                     ITK_PANIC("Hits was null"); 
       
   414                 }
       
   415             cpix_Query_destroy( query );
       
   416         } else  {
       
   417             ITK_PANIC("Could not create query"); 
       
   418         }
       
   419     }
       
   420 
       
   421 
       
   422     cpix_IdxSearcher * searcher(Itk::TestMgr * )
       
   423     {
       
   424         if (searcher_ == NULL)
       
   425             {
       
   426                 cpix_Result
       
   427                     result;
       
   428                 searcher_ = cpix_IdxSearcher_openDb(&result,
       
   429                                                     SMSAPPCLASS);
       
   430                 if (searcher_ == NULL)
       
   431                     {
       
   432                         ITK_PANIC("Searcher could not be created");
       
   433                     }
       
   434             }
       
   435         return searcher_;
       
   436     }
       
   437 };
       
   438 
       
   439 
       
   440 
       
   441 
       
   442 
       
   443 /**
       
   444  * This test case is incomplete, it is supposed to test for a fix for
       
   445  * the LuceneError flying through the catch(...) problem - but the
       
   446  * real cause is still unidentified, so this test is not enabled yet.
       
   447  */
       
   448 class CLuceneErrorBugCtxt : public Itk::ITestContext
       
   449 {
       
   450 private:
       
   451     SmsIdxUtil * idxUtil_;
       
   452     
       
   453     cpix_Analyzer * analyzer_;
       
   454     cpix_Query    * query_;
       
   455     cpix_QueryParser * queryParser_;
       
   456 
       
   457 
       
   458 public:
       
   459 
       
   460     CLuceneErrorBugCtxt()
       
   461         : idxUtil_(NULL),
       
   462           analyzer_(NULL),
       
   463           query_(NULL),
       
   464           queryParser_(NULL)
       
   465     {
       
   466         ;
       
   467     }
       
   468 
       
   469 
       
   470     ~CLuceneErrorBugCtxt()
       
   471     {
       
   472         cleanup();
       
   473     }
       
   474 
       
   475 
       
   476     void setup() throw (Itk::PanicExc)
       
   477     {
       
   478         SetupSentry
       
   479             ss(*this);
       
   480 
       
   481         idxUtil_ = new SmsIdxUtil;
       
   482         idxUtil_->init(true);
       
   483 
       
   484         cpix_Result
       
   485             result;
       
   486 
       
   487         analyzer_ = cpix_CreateSimpleAnalyzer(&result);
       
   488         if (cpix_Failed(&result))
       
   489             {
       
   490                 ITK_PANIC("Analyzer could not be created");
       
   491             }
       
   492 
       
   493 
       
   494         queryParser_ = cpix_QueryParser_create(&result,
       
   495                                                LBODY_FIELD,
       
   496                                                analyzer_);
       
   497 
       
   498         if (cpix_Failed(&result))
       
   499             {
       
   500                 ITK_PANIC("QueryParser could not be create4d");
       
   501             }
       
   502 
       
   503         query_ = cpix_QueryParser_parse(queryParser_,
       
   504                                         L"c*");
       
   505 
       
   506         if (query_ == NULL)
       
   507             {
       
   508                 ITK_PANIC("Query could not be created for 'c*'");
       
   509             }
       
   510     
       
   511         ss.setupComplete();
       
   512     }
       
   513     
       
   514 
       
   515     void tearDown() throw ()
       
   516     {
       
   517         cleanup();
       
   518     }
       
   519 
       
   520 
       
   521     void indexGeneratedLines(Itk::TestMgr * testMgr)
       
   522     {
       
   523         static const int
       
   524             wordsPerLine = 10;
       
   525 
       
   526         // we generate a lot of lines, like "a... a... a...",
       
   527         // "b... b... b...", ..., "j... j... j..." even if what we are
       
   528         // interested in is "c... c... c...". Reason: we need a big
       
   529         // index to produce crash-failure.
       
   530         static const int
       
   531             prefixCount = 10;
       
   532 
       
   533         std::wstring
       
   534             lines[prefixCount];
       
   535 
       
   536         for (int i = 0; i < 1030; ++i)
       
   537             {
       
   538                 if (i % 50 == 0)
       
   539                     {
       
   540                         ITK_DBGMSG(testMgr,
       
   541                                    ".");
       
   542                     }
       
   543                 
       
   544 
       
   545                 if (i % wordsPerLine == 0)
       
   546                     {
       
   547                         for (int j = 0; j < prefixCount; ++j)
       
   548                             {
       
   549                                 lines[j] = L'a' + j;
       
   550                             }
       
   551                     }
       
   552                 else
       
   553                     {
       
   554                         for (int j = 0; j < prefixCount; ++j)
       
   555                             {
       
   556                                 lines[j] += L' ';
       
   557                                 lines[j] += L'a' + j;
       
   558                             }
       
   559                     }
       
   560                 
       
   561                 std::wstring
       
   562                     postfix;
       
   563                 
       
   564                 static const int
       
   565                     charNum = int('z') - int('a') + 1;
       
   566                 static const int
       
   567                     digits = 4;
       
   568                 
       
   569                 // we generate a postfix
       
   570                 int
       
   571                     generator = i;
       
   572                 for (int d = 0; d < digits; ++d)
       
   573                     {
       
   574                         postfix += char('a' + generator % charNum);
       
   575                         generator /= charNum;
       
   576                     }
       
   577                 
       
   578                 for (int j = 0; j < prefixCount; ++j)
       
   579                     {
       
   580                         lines[j] += postfix;
       
   581                         
       
   582                         if (i % wordsPerLine == (wordsPerLine - 1))
       
   583                             {
       
   584                                 idxUtil_->indexSms(i - j,
       
   585                                                    lines[j].c_str(),
       
   586                                                    analyzer_,
       
   587                                                    testMgr,
       
   588                                                    false); // addition, not update
       
   589 
       
   590                                 ITK_ASSERT(testMgr,
       
   591                                            cpix_Succeeded(idxUtil_->idxDb()),
       
   592                                            "Addition of c... words should have succeeded");
       
   593                             }
       
   594                     }
       
   595             }
       
   596     }
       
   597 
       
   598 
       
   599     void searchCWildCard(Itk::TestMgr * testMgr)
       
   600     {
       
   601         cpix_Hits
       
   602             * hits = cpix_IdxDb_search(idxUtil_->idxDb(),
       
   603                                        query_);
       
   604 
       
   605         ITK_EXPECT(testMgr,
       
   606                    cpix_Failed(idxUtil_->idxDb()),
       
   607                    "Wildcard search 'c*' should fail gracefully");
       
   608 
       
   609         cpix_Hits_destroy(hits);
       
   610     }
       
   611 
       
   612 
       
   613 
       
   614 private:
       
   615     void cleanup()
       
   616     {
       
   617         cpix_Analyzer_destroy(analyzer_);
       
   618         analyzer_ = NULL;
       
   619 
       
   620         cpix_Query_destroy(query_);
       
   621         query_ = NULL;
       
   622 
       
   623         delete idxUtil_;
       
   624         idxUtil_ = NULL;
       
   625 
       
   626         cpix_QueryParser_destroy(queryParser_);
       
   627         queryParser_ = NULL;
       
   628     }
       
   629 };
       
   630 
       
   631 
       
   632 Itk::TesterBase * CreateCLuceneErrorTests()
       
   633 {
       
   634     using namespace Itk;
       
   635 
       
   636     CLuceneErrorBugCtxt
       
   637         * cebc = new CLuceneErrorBugCtxt;
       
   638     ContextTester
       
   639         * ct = new ContextTester("clerror",
       
   640                                  cebc);
       
   641 
       
   642     ct->add("indexGeneratedLines",
       
   643             cebc,
       
   644             &CLuceneErrorBugCtxt::indexGeneratedLines,
       
   645             "indexGeneratedLines");
       
   646     ct->add("searchCWildCard",
       
   647             cebc,
       
   648             &CLuceneErrorBugCtxt::searchCWildCard);
       
   649 
       
   650     return ct;
       
   651 }
       
   652 
       
   653 
       
   654 Itk::TesterBase * CreateDestructiveTests()
       
   655 {
       
   656     using namespace Itk;
       
   657     
       
   658     DestructiveTests* context = new DestructiveTests(); 
       
   659 
       
   660     SuiteTester
       
   661         * suiteTester = new Itk::ContextTester("destructive", context);
       
   662 
       
   663     suiteTester->add( "stackUnwinding", 
       
   664                     context,
       
   665                     &DestructiveTests::testStackunwinding );
       
   666 
       
   667 #define TEST "writingWhenHitIterating"
       
   668     suiteTester->add(TEST, 
       
   669                      context,
       
   670                      &DestructiveTests::testWritingWhenHitIterating,
       
   671                      TEST);
       
   672 #undef TEST
       
   673 
       
   674 #define TEST "writingWhenHitIterating2"
       
   675     suiteTester->add(TEST, 
       
   676                      context,
       
   677                      &DestructiveTests::testWritingWhenHitIterating2,
       
   678                      TEST);
       
   679 #undef TEST
       
   680 
       
   681     suiteTester->add("invalidation", 
       
   682 					 context,
       
   683                      &DestructiveTests::testInvalidation,
       
   684                      "invalidation");
       
   685                 
       
   686     return suiteTester;
       
   687 }