LCOV - code coverage report
Current view: top level - tests - api_closedb.cc (source / functions) Hit Total Coverage
Test: Test Coverage for xapian-core 954b5873a738 Lines: 233 236 98.7 %
Date: 2019-06-30 05:20:33 Functions: 14 14 100.0 %
Branches: 516 2454 21.0 %

           Branch data     Line data    Source code
       1                 :            : /** @file api_closedb.cc
       2                 :            :  * @brief Tests of closing databases.
       3                 :            :  */
       4                 :            : /* Copyright 2008,2009 Lemur Consulting Ltd
       5                 :            :  * Copyright 2009,2012,2015 Olly Betts
       6                 :            :  *
       7                 :            :  * This program is free software; you can redistribute it and/or modify
       8                 :            :  * it under the terms of the GNU General Public License as published by
       9                 :            :  * the Free Software Foundation; either version 2 of the License, or
      10                 :            :  * (at your option) any later version.
      11                 :            :  *
      12                 :            :  * This program is distributed in the hope that it will be useful,
      13                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15                 :            :  * GNU General Public License for more details.
      16                 :            :  *
      17                 :            :  * You should have received a copy of the GNU General Public License
      18                 :            :  * along with this program; if not, write to the Free Software
      19                 :            :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
      20                 :            :  */
      21                 :            : 
      22                 :            : #include <config.h>
      23                 :            : 
      24                 :            : #include "api_closedb.h"
      25                 :            : 
      26                 :            : #include <xapian.h>
      27                 :            : 
      28                 :            : #include "safeunistd.h"
      29                 :            : 
      30                 :            : #include "apitest.h"
      31                 :            : #include "testutils.h"
      32                 :            : 
      33                 :            : using namespace std;
      34                 :            : 
      35                 :            : #define COUNT_CLOSEDEXC(CODE) \
      36                 :            :     try { \
      37                 :            :         CODE; \
      38                 :            :     } catch (const Xapian::DatabaseClosedError &) { \
      39                 :            :         ++closedexc_count; \
      40                 :            :     }
      41                 :            : 
      42                 :            : #define IF_NOT_CLOSEDEXC(CODE) \
      43                 :            :     do { \
      44                 :            :         hadexc = false; \
      45                 :            :         try { \
      46                 :            :             CODE; \
      47                 :            :         } catch (const Xapian::DatabaseClosedError &) { \
      48                 :            :             ++closedexc_count; \
      49                 :            :             hadexc = true; \
      50                 :            :         } \
      51                 :            :     } while (false); if (hadexc)
      52                 :            : 
      53                 :            : // Iterators used by closedb1.
      54         [ +  - ]:         21 : struct closedb1_iterators {
      55                 :            :     Xapian::Database db;
      56                 :            :     Xapian::Document doc1;
      57                 :            :     Xapian::PostingIterator pl1;
      58                 :            :     Xapian::PostingIterator pl2;
      59                 :            :     Xapian::PostingIterator pl1end;
      60                 :            :     Xapian::PostingIterator pl2end;
      61                 :            :     Xapian::TermIterator tl1;
      62                 :            :     Xapian::TermIterator tlend;
      63                 :            :     Xapian::TermIterator atl1;
      64                 :            :     Xapian::TermIterator atlend;
      65                 :            :     Xapian::PositionIterator pil1;
      66                 :            :     Xapian::PositionIterator pilend;
      67                 :            : 
      68                 :         14 :     void setup(Xapian::Database db_) {
      69                 :         14 :         db = db_;
      70                 :            : 
      71                 :            :         // Set up the iterators for the test.
      72 [ +  - ][ +  - ]:         14 :         pl1 = db.postlist_begin("paragraph");
                 [ +  - ]
      73 [ +  - ][ +  - ]:         14 :         pl2 = db.postlist_begin("this");
                 [ +  - ]
      74                 :         14 :         ++pl2;
      75 [ +  - ][ +  - ]:         14 :         pl1end = db.postlist_end("paragraph");
      76 [ +  - ][ +  - ]:         14 :         pl2end = db.postlist_end("this");
      77         [ +  - ]:         14 :         tl1 = db.termlist_begin(1);
      78         [ +  - ]:         14 :         tlend = db.termlist_end(1);
      79 [ +  - ][ +  - ]:         14 :         atl1 = db.allterms_begin("t");
                 [ +  - ]
      80 [ +  - ][ +  - ]:         14 :         atlend = db.allterms_end("t");
      81 [ +  - ][ +  - ]:         14 :         pil1 = db.positionlist_begin(1, "paragraph");
                 [ +  - ]
      82 [ +  - ][ +  - ]:         14 :         pilend = db.positionlist_end(1, "paragraph");
      83                 :         14 :     }
      84                 :            : 
      85                 :         14 :     int perform() {
      86                 :         14 :         int closedexc_count = 0;
      87                 :            :         bool hadexc;
      88                 :            : 
      89                 :            :         // Getting a document may throw closed.
      90 [ +  + ][ +  - ]:         14 :         IF_NOT_CLOSEDEXC(doc1 = db.get_document(1)) {
         [ +  + ][ -  + ]
      91 [ +  + ][ +  - ]:          6 :             COUNT_CLOSEDEXC(TEST_EQUAL(doc1.get_data().substr(0, 33),
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ -  + ][ -  + ]
      92                 :            :                                        "This is a test document used with"));
      93         [ -  + ]:          6 :             COUNT_CLOSEDEXC(doc1.termlist_begin());
      94                 :            :         }
      95                 :            : 
      96                 :            :         // Causing the database to access its files raises the "database
      97                 :            :         // closed" error.
      98 [ +  - ][ +  + ]:         14 :         COUNT_CLOSEDEXC(db.postlist_begin("paragraph"));
                 [ -  + ]
      99 [ +  + ][ +  + ]:         21 :         COUNT_CLOSEDEXC(db.get_document(1).get_value(1));
         [ -  + ][ -  + ]
     100         [ +  + ]:         21 :         COUNT_CLOSEDEXC(db.termlist_begin(1));
     101 [ +  - ][ +  + ]:         14 :         COUNT_CLOSEDEXC(db.positionlist_begin(1, "paragraph"));
                 [ -  + ]
     102 [ +  - ][ +  + ]:         14 :         COUNT_CLOSEDEXC(db.allterms_begin());
                 [ -  + ]
     103 [ +  - ][ +  + ]:         14 :         COUNT_CLOSEDEXC(db.allterms_begin("p"));
                 [ -  + ]
     104 [ +  - ][ +  + ]:         14 :         COUNT_CLOSEDEXC(db.get_termfreq("paragraph"));
                 [ -  + ]
     105 [ +  - ][ +  + ]:         14 :         COUNT_CLOSEDEXC(db.get_collection_freq("paragraph"));
                 [ -  + ]
     106 [ +  - ][ +  + ]:         17 :         COUNT_CLOSEDEXC(db.term_exists("paragraph"));
         [ -  + ][ -  + ]
     107 [ +  + ][ -  + ]:         20 :         COUNT_CLOSEDEXC(db.get_value_freq(1));
     108 [ +  + ][ -  + ]:         20 :         COUNT_CLOSEDEXC(db.get_value_lower_bound(1));
     109 [ +  + ][ -  + ]:         24 :         COUNT_CLOSEDEXC(db.get_value_upper_bound(1));
     110 [ +  + ][ -  + ]:         24 :         COUNT_CLOSEDEXC(db.valuestream_begin(1));
     111 [ +  + ][ -  + ]:         24 :         COUNT_CLOSEDEXC(db.get_doclength(1));
     112 [ +  + ][ -  + ]:         28 :         COUNT_CLOSEDEXC(db.get_unique_terms(1));
     113                 :            : 
     114                 :            :         // Reopen raises the "database closed" error.
     115         [ +  + ]:         21 :         COUNT_CLOSEDEXC(db.reopen());
     116                 :            : 
     117 [ -  + ][ #  # ]:         14 :         TEST_NOT_EQUAL(pl1, pl1end);
     118 [ -  + ][ #  # ]:         14 :         TEST_NOT_EQUAL(pl2, pl2end);
     119 [ -  + ][ #  # ]:         14 :         TEST_NOT_EQUAL(tl1, tlend);
     120 [ -  + ][ #  # ]:         14 :         TEST_NOT_EQUAL(atl1, atlend);
     121 [ -  + ][ #  # ]:         14 :         TEST_NOT_EQUAL(pil1, pilend);
     122                 :            : 
     123 [ +  - ][ +  + ]:         15 :         COUNT_CLOSEDEXC(db.postlist_begin("paragraph"));
         [ -  + ][ -  + ]
     124                 :            : 
     125 [ +  + ][ -  + ]:         18 :         COUNT_CLOSEDEXC(TEST_EQUAL(*pl1, 1));
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ -  + ]
     126 [ +  + ][ -  + ]:         24 :         COUNT_CLOSEDEXC(TEST_EQUAL(pl1.get_doclength(), 28));
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ -  + ]
     127 [ +  + ][ -  + ]:         22 :         COUNT_CLOSEDEXC(TEST_EQUAL(pl1.get_unique_terms(), 21));
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ -  + ]
     128                 :            : 
     129 [ +  + ][ -  + ]:         18 :         COUNT_CLOSEDEXC(TEST_EQUAL(*pl2, 2));
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ -  + ]
     130 [ +  + ][ -  + ]:         24 :         COUNT_CLOSEDEXC(TEST_EQUAL(pl2.get_doclength(), 81));
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ -  + ]
     131 [ +  + ][ -  + ]:         21 :         COUNT_CLOSEDEXC(TEST_EQUAL(pl2.get_unique_terms(), 56));
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     132                 :            : 
     133 [ +  + ][ +  - ]:         15 :         COUNT_CLOSEDEXC(TEST_EQUAL(*tl1, "a"));
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ -  + ][ -  + ]
     134 [ +  + ][ -  + ]:         20 :         COUNT_CLOSEDEXC(TEST_EQUAL(tl1.get_wdf(), 2));
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ -  + ]
     135 [ +  + ][ -  + ]:         19 :         COUNT_CLOSEDEXC(TEST_EQUAL(tl1.get_termfreq(), 3));
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     136                 :            : 
     137 [ +  + ][ +  - ]:         16 :         COUNT_CLOSEDEXC(TEST_EQUAL(*atl1, "test"));
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ -  + ][ -  + ]
     138 [ +  + ][ -  + ]:         16 :         COUNT_CLOSEDEXC(TEST_EQUAL(atl1.get_termfreq(), 1));
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     139                 :            : 
     140 [ +  - ][ -  + ]:         15 :         COUNT_CLOSEDEXC(TEST_EQUAL(*pil1, 12));
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ -  + ]
     141                 :            : 
     142                 :            :         // Advancing the iterator may or may not raise an error, but if it
     143                 :            :         // doesn't it must return the correct answers.
     144                 :         14 :         bool advanced = false;
     145                 :            :         try {
     146         [ +  + ]:         14 :             ++pl1;
     147                 :         13 :             advanced = true;
     148         [ #  # ]:          1 :         } catch (const Xapian::DatabaseClosedError &) {}
     149                 :            : 
     150         [ +  + ]:         14 :         if (advanced) {
     151 [ +  - ][ -  + ]:         15 :             COUNT_CLOSEDEXC(TEST_EQUAL(*pl1, 2));
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ -  + ]
     152 [ +  + ][ -  + ]:         21 :             COUNT_CLOSEDEXC(TEST_EQUAL(pl1.get_doclength(), 81));
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ -  + ]
     153 [ +  + ][ -  + ]:         20 :             COUNT_CLOSEDEXC(TEST_EQUAL(pl1.get_unique_terms(), 56));
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ -  + ]
     154                 :            :         }
     155                 :            : 
     156                 :         14 :         advanced = false;
     157                 :            :         try {
     158         [ +  + ]:         14 :             ++pl2;
     159                 :         13 :             advanced = true;
     160         [ #  # ]:          1 :         } catch (const Xapian::DatabaseClosedError &) {}
     161                 :            : 
     162         [ +  + ]:         14 :         if (advanced) {
     163 [ +  - ][ -  + ]:         15 :             COUNT_CLOSEDEXC(TEST_EQUAL(*pl2, 3));
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ -  + ]
     164 [ +  + ][ -  + ]:         21 :             COUNT_CLOSEDEXC(TEST_EQUAL(pl2.get_doclength(), 15));
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ -  + ]
     165 [ +  + ][ -  + ]:         20 :             COUNT_CLOSEDEXC(TEST_EQUAL(pl2.get_unique_terms(), 14));
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ -  + ]
     166                 :            :         }
     167                 :            : 
     168                 :         14 :         advanced = false;
     169                 :            :         try {
     170         [ +  + ]:         14 :             ++tl1;
     171                 :         13 :             advanced = true;
     172                 :          1 :         } catch (const Xapian::DatabaseClosedError &) {}
     173                 :            : 
     174         [ +  + ]:         14 :         if (advanced) {
     175 [ +  - ][ +  - ]:         13 :             COUNT_CLOSEDEXC(TEST_EQUAL(*tl1, "api"));
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
           [ #  #  #  # ]
     176 [ +  - ][ -  + ]:         17 :             COUNT_CLOSEDEXC(TEST_EQUAL(tl1.get_wdf(), 1));
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ -  + ]
     177 [ +  + ][ -  + ]:         19 :             COUNT_CLOSEDEXC(TEST_EQUAL(tl1.get_termfreq(), 1));
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ -  + ]
     178                 :            :         }
     179                 :            : 
     180                 :         14 :         advanced = false;
     181                 :            :         try {
     182         [ +  + ]:         14 :             ++atl1;
     183                 :         12 :             advanced = true;
     184                 :          2 :         } catch (const Xapian::DatabaseClosedError &) {}
     185                 :            : 
     186         [ +  + ]:         14 :         if (advanced) {
     187 [ +  - ][ +  - ]:         12 :             COUNT_CLOSEDEXC(TEST_EQUAL(*atl1, "that"));
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
           [ #  #  #  # ]
     188 [ +  - ][ -  + ]:         12 :             COUNT_CLOSEDEXC(TEST_EQUAL(atl1.get_termfreq(), 2));
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     189                 :            :         }
     190                 :            : 
     191                 :         14 :         advanced = false;
     192                 :            :         try {
     193         [ +  - ]:         14 :             ++pil1;
     194                 :         14 :             advanced = true;
     195         [ #  # ]:          0 :         } catch (const Xapian::DatabaseClosedError &) {}
     196                 :            : 
     197         [ +  - ]:         14 :         if (advanced) {
     198 [ +  - ][ -  + ]:         14 :             COUNT_CLOSEDEXC(TEST_EQUAL(*pil1, 28));
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     199                 :            :         }
     200                 :            : 
     201                 :         14 :         return closedexc_count;
     202                 :            :     }
     203                 :            : };
     204                 :            : 
     205                 :            : // Test for closing a database
     206                 :          7 : DEFINE_TESTCASE(closedb1, backend) {
     207 [ +  - ][ +  - ]:          7 :     Xapian::Database db(get_database("apitest_simpledata"));
     208         [ +  - ]:         14 :     closedb1_iterators iters;
     209                 :            : 
     210                 :            :     // Run the test, checking that we get no "closed" exceptions.
     211 [ +  - ][ +  - ]:          7 :     iters.setup(db);
     212         [ +  - ]:          7 :     int closedexc_count = iters.perform();
     213 [ -  + ][ #  # ]:          7 :     TEST_EQUAL(closedexc_count, 0);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     214                 :            : 
     215                 :            :     // Setup for the next test.
     216 [ +  - ][ +  - ]:          7 :     iters.setup(db);
     217                 :            : 
     218                 :            :     // Close the database.
     219         [ +  - ]:          7 :     db.close();
     220                 :            : 
     221                 :            :     // Dup stdout to the fds which the database was using, to try to catch
     222                 :            :     // issues with lingering references to closed fds (regression test for
     223                 :            :     // early development versions of honey).
     224                 :         14 :     vector<int> fds;
     225         [ +  + ]:         49 :     for (int i = 0; i != 6; ++i) {
     226         [ +  - ]:         42 :         fds.push_back(dup(1));
     227                 :            :     }
     228                 :            : 
     229                 :            :     // Reopening a closed database should always raise DatabaseClosedError.
     230 [ +  - ][ -  + ]:          7 :     TEST_EXCEPTION(Xapian::DatabaseClosedError, db.reopen());
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ -  + ][ -  +  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
                 [ +  - ]
     231                 :            : 
     232                 :            :     // Run the test again, checking that we get some "closed" exceptions.
     233         [ +  - ]:          7 :     closedexc_count = iters.perform();
     234   [ -  +  #  #  :          7 :     TEST_NOT_EQUAL(closedexc_count, 0);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
     235                 :            : 
     236                 :            :     // get_description() shouldn't throw an exception.  Actually do something
     237                 :            :     // with the description, in case this method is marked as "pure" in the
     238                 :            :     // future.
     239 [ +  - ][ -  +  :          7 :     TEST(!db.get_description().empty());
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     240                 :            : 
     241                 :            :     // Calling close repeatedly is okay.
     242         [ +  - ]:          7 :     db.close();
     243                 :            : 
     244         [ +  + ]:         49 :     for (int fd : fds) {
     245         [ +  - ]:         42 :         close(fd);
     246                 :            :     }
     247                 :          7 :     return true;
     248                 :            : }
     249                 :            : 
     250                 :            : // Test closing a writable database, and that it drops the lock.
     251                 :          2 : DEFINE_TESTCASE(closedb2, writable && path) {
     252 [ +  - ][ +  - ]:          4 :     Xapian::WritableDatabase dbw1(get_named_writable_database("apitest_closedb2"));
                 [ +  - ]
     253 [ +  - ][ +  - ]:          4 :     TEST_EXCEPTION(Xapian::DatabaseLockError,
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ -  + ][ -  +  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
                 [ +  - ]
     254                 :            :                    Xapian::WritableDatabase db(get_named_writable_database_path("apitest_closedb2"),
     255                 :            :                                                Xapian::DB_OPEN));
     256         [ +  - ]:          2 :     dbw1.close();
     257 [ +  - ][ +  - ]:          4 :     Xapian::WritableDatabase dbw2 = get_named_writable_database("apitest_closedb2");
                 [ +  - ]
     258 [ +  - ][ +  - ]:          2 :     TEST_EXCEPTION(Xapian::DatabaseClosedError,
           [ -  +  #  #  
          #  #  #  #  #  
             #  #  #  #  
              # ][ -  + ]
           [ -  +  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           #  # ][ +  - ]
     259                 :            :                dbw1.postlist_begin("paragraph"));
     260 [ +  - ][ +  - ]:          2 :     TEST_EQUAL(dbw2.postlist_begin("paragraph"), dbw2.postlist_end("paragraph"));
         [ +  - ][ -  +  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     261                 :            : 
     262                 :          2 :     return true;
     263                 :            : }
     264                 :            : 
     265                 :            : /// Check API methods which might either work or throw an exception.
     266                 :          7 : DEFINE_TESTCASE(closedb3, backend) {
     267 [ +  - ][ +  - ]:          7 :     Xapian::Database db(get_database("etext"));
     268         [ +  - ]:         14 :     const string & uuid = db.get_uuid();
     269         [ +  - ]:          7 :     db.close();
     270                 :            :     try {
     271 [ +  - ][ -  + ]:          7 :         TEST_EQUAL(db.get_uuid(), uuid);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     272 [ #  # ][ -  + ]:          1 :     } catch (const Xapian::DatabaseClosedError &) {
     273                 :            :     }
     274                 :            :     try {
     275 [ +  + ][ -  + ]:          7 :         TEST(db.has_positions());
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     276 [ +  - ][ -  + ]:          2 :     } catch (const Xapian::DatabaseClosedError &) {
     277                 :            :     }
     278                 :            :     try {
     279 [ +  + ][ -  + ]:          7 :         TEST_EQUAL(db.get_doccount(), 566);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     280 [ +  - ][ -  + ]:          2 :     } catch (const Xapian::DatabaseClosedError &) {
     281                 :            :     }
     282                 :            :     try {
     283 [ +  + ][ -  + ]:          7 :         TEST_EQUAL(db.get_lastdocid(), 566);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     284 [ +  - ][ -  + ]:          2 :     } catch (const Xapian::DatabaseClosedError &) {
     285                 :            :     }
     286                 :            :     try {
     287 [ +  - ][ +  + ]:          7 :         TEST_REL(db.get_doclength_lower_bound(), <, db.get_avlength());
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     288 [ +  - ][ -  + ]:          2 :     } catch (const Xapian::DatabaseClosedError &) {
     289                 :            :     }
     290                 :            :     try {
     291 [ +  - ][ +  + ]:          7 :         TEST_REL(db.get_doclength_upper_bound(), >, db.get_avlength());
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     292         [ +  - ]:          1 :     } catch (const Xapian::DatabaseClosedError &) {
     293                 :            :     }
     294                 :            :     try {
     295 [ +  - ][ +  + ]:          7 :         TEST(db.get_wdf_upper_bound("king"));
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ -  + ]
     296 [ +  - ][ -  + ]:          7 :     } catch (const Xapian::DatabaseClosedError &) {
     297                 :            :     }
     298                 :            :     try {
     299                 :            :         // For non-remote databases, keep_alive() is a no-op anyway.
     300         [ +  + ]:          7 :         db.keep_alive();
     301         [ +  - ]:          2 :     } catch (const Xapian::DatabaseClosedError &) {
     302                 :            :     }
     303                 :          7 :     return true;
     304                 :            : }
     305                 :            : 
     306                 :            : /// Regression test for bug fixed in 1.1.4 - close() should implicitly commit().
     307                 :          4 : DEFINE_TESTCASE(closedb4, writable && !inmemory) {
     308 [ +  - ][ +  - ]:          4 :     Xapian::WritableDatabase wdb(get_writable_database());
     309 [ +  - ][ +  - ]:          4 :     wdb.add_document(Xapian::Document());
     310 [ +  - ][ -  + ]:          4 :     TEST_EQUAL(wdb.get_doccount(), 1);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     311         [ +  - ]:          4 :     wdb.close();
     312         [ +  - ]:          8 :     Xapian::Database db(get_writable_database_as_database());
     313 [ +  - ][ -  + ]:          4 :     TEST_EQUAL(db.get_doccount(), 1);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     314                 :          4 :     return true;
     315                 :            : }
     316                 :            : 
     317                 :            : /// Test the effects of close() on transactions
     318                 :          3 : DEFINE_TESTCASE(closedb5, transactions) {
     319                 :            :     {
     320                 :            :         // If a transaction is active, close() shouldn't implicitly commit().
     321 [ +  - ][ +  - ]:          3 :         Xapian::WritableDatabase wdb = get_writable_database();
     322         [ +  - ]:          3 :         wdb.begin_transaction();
     323 [ +  - ][ +  - ]:          3 :         wdb.add_document(Xapian::Document());
     324 [ +  - ][ -  + ]:          3 :         TEST_EQUAL(wdb.get_doccount(), 1);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     325         [ +  - ]:          3 :         wdb.close();
     326         [ +  - ]:          6 :         Xapian::Database db = get_writable_database_as_database();
     327 [ +  - ][ -  + ]:          6 :         TEST_EQUAL(db.get_doccount(), 0);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     328                 :            :     }
     329                 :            : 
     330                 :            :     {
     331                 :            :         // Same test but for an unflushed transaction.
     332 [ +  - ][ +  - ]:          3 :         Xapian::WritableDatabase wdb = get_writable_database();
     333         [ +  - ]:          3 :         wdb.begin_transaction(false);
     334 [ +  - ][ +  - ]:          3 :         wdb.add_document(Xapian::Document());
     335 [ +  - ][ -  + ]:          3 :         TEST_EQUAL(wdb.get_doccount(), 1);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     336         [ +  - ]:          3 :         wdb.close();
     337         [ +  - ]:          6 :         Xapian::Database db = get_writable_database_as_database();
     338 [ +  - ][ -  + ]:          6 :         TEST_EQUAL(db.get_doccount(), 0);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     339                 :            :     }
     340                 :            : 
     341                 :            :     {
     342                 :            :         // commit_transaction() throws InvalidOperationError when
     343                 :            :         // not in a transaction.
     344 [ +  - ][ +  - ]:          3 :         Xapian::WritableDatabase wdb = get_writable_database();
     345         [ +  - ]:          3 :         wdb.close();
     346 [ +  - ][ -  + ]:          5 :         TEST_EXCEPTION(Xapian::InvalidOperationError,
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ -  + ][ -  +  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
         [ +  - ][ -  + ]
     347                 :            :                        wdb.commit_transaction());
     348                 :            : 
     349                 :            :         // begin_transaction() is no-op or throws DatabaseClosedError. We may be
     350                 :            :         // able to call db.begin_transaction(), but we can't make any changes
     351                 :            :         // inside that transaction. If begin_transaction() succeeds, then
     352                 :            :         // commit_transaction() either end the transaction or throw
     353                 :            :         // DatabaseClosedError.
     354                 :          3 :         bool advanced = false;
     355                 :            :         try {
     356         [ +  + ]:          3 :             wdb.begin_transaction();
     357                 :          1 :             advanced = true;
     358   [ +  -  #  # ]:          2 :         } catch (const Xapian::DatabaseClosedError &) {
     359                 :            :         }
     360         [ +  + ]:          3 :         if (advanced) {
     361                 :            :             try {
     362         [ +  - ]:          1 :                 wdb.commit_transaction();
     363         [ #  # ]:          0 :             } catch (const Xapian::DatabaseClosedError &) {
     364                 :            :             }
     365                 :          3 :         }
     366                 :            :     }
     367                 :            : 
     368                 :            :     {
     369                 :            :         // Same test but for cancel_transaction().
     370 [ +  - ][ +  - ]:          3 :         Xapian::WritableDatabase wdb = get_writable_database();
     371         [ +  - ]:          3 :         wdb.close();
     372 [ +  - ][ -  +  :          5 :         TEST_EXCEPTION(Xapian::InvalidOperationError,
          #  #  #  #  #  
          #  #  #  #  #  
           #  # ][ -  + ]
           [ -  +  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           #  # ][ +  - ]
                 [ -  + ]
     373                 :            :                        wdb.cancel_transaction());
     374                 :            : 
     375                 :          3 :         bool advanced = false;
     376                 :            :         try {
     377         [ +  + ]:          3 :             wdb.begin_transaction();
     378                 :          1 :             advanced = true;
     379 [ +  - ][ -  + ]:          3 :         } catch (const Xapian::DatabaseClosedError &) {
     380                 :            :         }
     381         [ +  + ]:          3 :         if (advanced) {
     382                 :            :             try {
     383         [ -  + ]:          2 :                 wdb.cancel_transaction();
     384         [ +  - ]:          1 :             } catch (const Xapian::DatabaseClosedError &) {
     385                 :            :             }
     386                 :          3 :         }
     387                 :            :     }
     388                 :            : 
     389                 :          3 :     return true;
     390                 :            : }
     391                 :            : 
     392                 :            : /// Database::keep_alive() should fail after close() for a remote database.
     393                 :          2 : DEFINE_TESTCASE(closedb6, remote) {
     394 [ +  - ][ +  - ]:          4 :     Xapian::Database db(get_database("etext"));
                 [ -  + ]
     395         [ +  - ]:          2 :     db.close();
     396                 :            : 
     397                 :            :     try {
     398         [ -  + ]:          2 :         db.keep_alive();
     399                 :          0 :         return false;
     400         [ +  - ]:          2 :     } catch (const Xapian::DatabaseClosedError &) {
     401                 :            :     }
     402                 :          2 :     return true;
     403                 :            : }
     404                 :            : 
     405                 :            : // Test WritableDatabase methods.
     406                 :          5 : DEFINE_TESTCASE(closedb7, writable) {
     407 [ +  - ][ +  - ]:          5 :     Xapian::WritableDatabase db(get_writable_database());
     408 [ +  - ][ +  - ]:          7 :     db.add_document(Xapian::Document());
                 [ -  + ]
     409         [ +  - ]:          5 :     db.close();
     410                 :            : 
     411                 :            :     // Since we can't make any changes which need to be committed,
     412                 :            :     // db.commit() is a no-op, and so doesn't have to fail.
     413                 :            :     try {
     414         [ +  + ]:          5 :         db.commit();
     415         [ +  - ]:          2 :     } catch (const Xapian::DatabaseClosedError &) {
     416                 :            :     }
     417                 :            : 
     418 [ +  - ][ +  - ]:          5 :     TEST_EXCEPTION(Xapian::DatabaseClosedError,
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ -  + ]
           [ -  +  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           #  # ][ +  - ]
     419                 :            :                    db.add_document(Xapian::Document()));
     420 [ +  - ][ -  +  :          5 :     TEST_EXCEPTION(Xapian::DatabaseClosedError,
          #  #  #  #  #  
          #  #  #  #  #  
           #  # ][ -  + ]
           [ -  +  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           #  # ][ +  - ]
     421                 :            :                    db.delete_document(1));
     422 [ +  - ][ +  - ]:          5 :     TEST_EXCEPTION(Xapian::DatabaseClosedError,
           [ -  +  #  #  
          #  #  #  #  #  
             #  #  #  #  
              # ][ -  + ]
           [ -  +  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           #  # ][ +  - ]
     423                 :            :                    db.replace_document(1, Xapian::Document()));
     424 [ +  - ][ +  - ]:          5 :     TEST_EXCEPTION(Xapian::DatabaseClosedError,
           [ -  +  #  #  
          #  #  #  #  #  
             #  #  #  #  
              # ][ -  + ]
           [ -  +  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           #  # ][ +  - ]
     425                 :            :                    db.replace_document(2, Xapian::Document()));
     426 [ +  - ][ +  - ]:          5 :     TEST_EXCEPTION(Xapian::DatabaseClosedError,
         [ +  - ][ -  +  
          #  #  #  #  #  
          #  #  #  #  #  
           #  # ][ -  + ]
           [ -  +  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           #  # ][ +  - ]
     427                 :            :                    db.replace_document("Qi", Xapian::Document()));
     428                 :            : 
     429                 :          5 :     return true;
     430                 :            : }
     431                 :            : 
     432                 :            : // Test spelling related methods.
     433                 :          1 : DEFINE_TESTCASE(closedb8, writable && spelling) {
     434 [ +  - ][ +  - ]:          1 :     Xapian::WritableDatabase db(get_writable_database());
     435 [ +  - ][ +  - ]:          1 :     db.add_spelling("pneumatic");
     436 [ +  - ][ +  - ]:          1 :     db.add_spelling("pneumonia");
     437         [ +  - ]:          1 :     db.close();
     438                 :            : 
     439 [ +  - ][ +  - ]:          1 :     TEST_EXCEPTION(Xapian::DatabaseClosedError,
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ -  + ]
           [ -  +  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           #  # ][ +  - ]
     440                 :            :                    db.add_spelling("penmanship"));
     441 [ +  - ][ +  - ]:          1 :     TEST_EXCEPTION(Xapian::DatabaseClosedError,
           [ -  +  #  #  
          #  #  #  #  #  
             #  #  #  #  
              # ][ -  + ]
           [ -  +  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           #  # ][ +  - ]
     442                 :            :                    db.remove_spelling("pneumatic"));
     443 [ +  - ][ +  - ]:          1 :     TEST_EXCEPTION(Xapian::DatabaseClosedError,
           [ -  +  #  #  
          #  #  #  #  #  
             #  #  #  #  
              # ][ -  + ]
           [ -  +  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           #  # ][ +  - ]
     444                 :            :                    db.get_spelling_suggestion("newmonia"));
     445 [ +  - ][ -  +  :          1 :     TEST_EXCEPTION(Xapian::DatabaseClosedError,
          #  #  #  #  #  
          #  #  #  #  #  
           #  # ][ -  + ]
           [ -  +  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           #  # ][ +  - ]
     446                 :            :                    db.spellings_begin());
     447                 :            : 
     448                 :          1 :     return true;
     449                 :            : }
     450                 :            : 
     451                 :            : // Test synonym related methods.
     452                 :          2 : DEFINE_TESTCASE(closedb9, writable && synonyms) {
     453 [ +  - ][ +  - ]:          2 :     Xapian::WritableDatabase db(get_writable_database());
     454 [ +  - ][ +  - ]:          2 :     db.add_synonym("color", "colour");
                 [ +  - ]
     455 [ +  - ][ +  - ]:          2 :     db.add_synonym("honor", "honour");
                 [ +  - ]
     456         [ +  - ]:          2 :     db.close();
     457                 :            : 
     458 [ +  - ][ +  - ]:          2 :     TEST_EXCEPTION(Xapian::DatabaseClosedError,
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ -  + ][ -  +  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
                 [ +  - ]
     459                 :            :                    db.add_synonym("behavior", "behaviour"));
     460 [ +  - ][ +  - ]:          2 :     TEST_EXCEPTION(Xapian::DatabaseClosedError,
         [ +  - ][ -  +  
          #  #  #  #  #  
          #  #  #  #  #  
           #  # ][ -  + ]
           [ -  +  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           #  # ][ +  - ]
     461                 :            :                    db.remove_synonym("honor", "honour"));
     462 [ +  - ][ +  - ]:          2 :     TEST_EXCEPTION(Xapian::DatabaseClosedError,
           [ -  +  #  #  
          #  #  #  #  #  
             #  #  #  #  
              # ][ -  + ]
           [ -  +  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           #  # ][ +  - ]
     463                 :            :                    db.clear_synonyms("honor"));
     464 [ +  - ][ +  - ]:          2 :     TEST_EXCEPTION(Xapian::DatabaseClosedError,
           [ -  +  #  #  
          #  #  #  #  #  
             #  #  #  #  
              # ][ -  + ]
           [ -  +  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           #  # ][ +  - ]
     465                 :            :                    db.synonyms_begin("color"));
     466 [ +  - ][ +  - ]:          2 :     TEST_EXCEPTION(Xapian::DatabaseClosedError,
           [ -  +  #  #  
          #  #  #  #  #  
             #  #  #  #  
              # ][ -  + ]
           [ -  +  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           #  # ][ +  - ]
     467                 :            :                    db.synonym_keys_begin());
     468                 :            : 
     469                 :          2 :     return true;
     470                 :            : }
     471                 :            : 
     472                 :            : // Test metadata related methods.
     473                 :          5 : DEFINE_TESTCASE(closedb10, writable && metadata) {
     474 [ +  - ][ +  - ]:          5 :     Xapian::WritableDatabase db(get_writable_database());
     475 [ +  - ][ +  - ]:          5 :     db.set_metadata("foo", "FOO");
                 [ +  - ]
     476 [ +  - ][ +  - ]:          5 :     db.set_metadata("bar", "BAR");
                 [ +  - ]
     477         [ +  - ]:          5 :     db.close();
     478                 :            : 
     479 [ +  - ][ +  - ]:          5 :     TEST_EXCEPTION(Xapian::DatabaseClosedError,
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ -  + ][ -  +  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
                 [ +  - ]
     480                 :            :                    db.set_metadata("test", "TEST"));
     481 [ +  - ][ +  - ]:          5 :     TEST_EXCEPTION(Xapian::DatabaseClosedError,
           [ -  +  #  #  
          #  #  #  #  #  
             #  #  #  #  
              # ][ -  + ]
           [ -  +  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           #  # ][ +  - ]
     482                 :            :                    db.get_metadata("foo"));
     483 [ +  - ][ +  - ]:          5 :     TEST_EXCEPTION(Xapian::DatabaseClosedError,
           [ -  +  #  #  
          #  #  #  #  #  
             #  #  #  #  
              # ][ -  + ]
           [ -  +  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           #  # ][ +  - ]
     484                 :            :                    db.get_metadata("bar"));
     485 [ +  - ][ +  - ]:          5 :     TEST_EXCEPTION(Xapian::DatabaseClosedError,
           [ -  +  #  #  
          #  #  #  #  #  
             #  #  #  #  
              # ][ -  + ]
           [ -  +  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           #  # ][ +  - ]
     486                 :            :                    db.metadata_keys_begin());
     487                 :            : 
     488                 :          5 :     return true;
     489                 :            : }

Generated by: LCOV version 1.11