Annotation of embedaddon/sqlite3/test/exclusive.test, revision 1.1.1.1

1.1       misho       1: # 2007 March 24
                      2: #
                      3: # The author disclaims copyright to this source code.  In place of
                      4: # a legal notice, here is a blessing:
                      5: #
                      6: #    May you do good and not evil.
                      7: #    May you find forgiveness for yourself and forgive others.
                      8: #    May you share freely, never taking more than you give.
                      9: #
                     10: #***********************************************************************
                     11: # This file implements regression tests for SQLite library. The focus
                     12: # of these tests is exclusive access mode (i.e. the thing activated by 
                     13: # "PRAGMA locking_mode = EXCLUSIVE").
                     14: #
                     15: # $Id: exclusive.test,v 1.15 2009/06/26 12:30:40 danielk1977 Exp $
                     16: 
                     17: set testdir [file dirname $argv0]
                     18: source $testdir/tester.tcl
                     19: 
                     20: ifcapable {!pager_pragmas} {
                     21:   finish_test
                     22:   return
                     23: }
                     24: 
                     25: forcedelete test2.db-journal
                     26: forcedelete test2.db
                     27: forcedelete test3.db-journal
                     28: forcedelete test3.db
                     29: forcedelete test4.db-journal
                     30: forcedelete test4.db
                     31: 
                     32: #----------------------------------------------------------------------
                     33: # Test cases exclusive-1.X test the PRAGMA logic.
                     34: #
                     35: do_test exclusive-1.0 {
                     36:   execsql {
                     37:     pragma locking_mode;
                     38:     pragma main.locking_mode;
                     39:     pragma temp.locking_mode;
                     40:   } 
                     41: } [list normal normal exclusive]
                     42: do_test exclusive-1.1 {
                     43:   execsql {
                     44:     pragma locking_mode = exclusive;
                     45:   } 
                     46: } {exclusive}
                     47: do_test exclusive-1.2 {
                     48:   execsql {
                     49:     pragma locking_mode;
                     50:     pragma main.locking_mode;
                     51:     pragma temp.locking_mode;
                     52:   } 
                     53: } [list exclusive exclusive exclusive]
                     54: do_test exclusive-1.3 {
                     55:   execsql {
                     56:     pragma locking_mode = normal;
                     57:   } 
                     58: } {normal}
                     59: do_test exclusive-1.4 {
                     60:   execsql {
                     61:     pragma locking_mode;
                     62:     pragma main.locking_mode;
                     63:     pragma temp.locking_mode;
                     64:   } 
                     65: } [list normal normal exclusive]
                     66: do_test exclusive-1.5 {
                     67:   execsql {
                     68:     pragma locking_mode = invalid;
                     69:   } 
                     70: } {normal}
                     71: do_test exclusive-1.6 {
                     72:   execsql {
                     73:     pragma locking_mode;
                     74:     pragma main.locking_mode;
                     75:     pragma temp.locking_mode;
                     76:   } 
                     77: } [list normal normal exclusive]
                     78: ifcapable attach {
                     79:   do_test exclusive-1.7 {
                     80:     execsql {
                     81:       pragma locking_mode = exclusive;
                     82:       ATTACH 'test2.db' as aux;
                     83:     }
                     84:     execsql {
                     85:       pragma main.locking_mode;
                     86:       pragma aux.locking_mode;
                     87:     }
                     88:   } {exclusive exclusive}
                     89:   do_test exclusive-1.8 {
                     90:     execsql {
                     91:       pragma main.locking_mode = normal;
                     92:     }
                     93:     execsql {
                     94:       pragma main.locking_mode;
                     95:       pragma temp.locking_mode;
                     96:       pragma aux.locking_mode;
                     97:     }
                     98:   } [list normal exclusive exclusive]
                     99:   do_test exclusive-1.9 {
                    100:     execsql {
                    101:       pragma locking_mode;
                    102:     }
                    103:   } {exclusive}
                    104:   do_test exclusive-1.10 {
                    105:     execsql {
                    106:       ATTACH 'test3.db' as aux2;
                    107:     }
                    108:     execsql {
                    109:       pragma main.locking_mode;
                    110:       pragma aux.locking_mode;
                    111:       pragma aux2.locking_mode;
                    112:     }
                    113:   } {normal exclusive exclusive}
                    114:   do_test exclusive-1.11 {
                    115:     execsql {
                    116:       pragma aux.locking_mode = normal;
                    117:     }
                    118:     execsql {
                    119:       pragma main.locking_mode;
                    120:       pragma aux.locking_mode;
                    121:       pragma aux2.locking_mode;
                    122:     }
                    123:   } {normal normal exclusive}
                    124:   do_test exclusive-1.12 {
                    125:     execsql {
                    126:       pragma locking_mode = normal;
                    127:     }
                    128:     execsql {
                    129:       pragma main.locking_mode;
                    130:       pragma temp.locking_mode;
                    131:       pragma aux.locking_mode;
                    132:       pragma aux2.locking_mode;
                    133:     }
                    134:   } [list normal exclusive normal normal]
                    135:   do_test exclusive-1.13 {
                    136:     execsql {
                    137:       ATTACH 'test4.db' as aux3;
                    138:     }
                    139:     execsql {
                    140:       pragma main.locking_mode;
                    141:       pragma temp.locking_mode;
                    142:       pragma aux.locking_mode;
                    143:       pragma aux2.locking_mode;
                    144:       pragma aux3.locking_mode;
                    145:     }
                    146:   } [list normal exclusive normal normal normal]
                    147:   
                    148:   do_test exclusive-1.99 {
                    149:     execsql {
                    150:       DETACH aux;
                    151:       DETACH aux2;
                    152:       DETACH aux3;
                    153:     }
                    154:   } {}
                    155: }
                    156: 
                    157: #----------------------------------------------------------------------
                    158: # Test cases exclusive-2.X verify that connections in exclusive 
                    159: # locking_mode do not relinquish locks.
                    160: #
                    161: do_test exclusive-2.0 {
                    162:   execsql {
                    163:     CREATE TABLE abc(a, b, c);
                    164:     INSERT INTO abc VALUES(1, 2, 3);
                    165:     PRAGMA locking_mode = exclusive;
                    166:   }
                    167: } {exclusive}
                    168: do_test exclusive-2.1 {
                    169:   sqlite3 db2 test.db
                    170:   execsql {
                    171:     INSERT INTO abc VALUES(4, 5, 6);
                    172:     SELECT * FROM abc;
                    173:   } db2
                    174: } {1 2 3 4 5 6}
                    175: do_test exclusive-2.2 {
                    176:   # This causes connection 'db' (in exclusive mode) to establish 
                    177:   # a shared-lock on the db. The other connection should now be
                    178:   # locked out as a writer.
                    179:   execsql {
                    180:     SELECT * FROM abc;
                    181:   } db
                    182: } {1 2 3 4 5 6}
                    183: do_test exclusive-2.4 {
                    184:   execsql {
                    185:     SELECT * FROM abc;
                    186:   } db2
                    187: } {1 2 3 4 5 6}
                    188: do_test exclusive-2.5 {
                    189:   catchsql {
                    190:     INSERT INTO abc VALUES(7, 8, 9);
                    191:   } db2
                    192: } {1 {database is locked}}
                    193: sqlite3_soft_heap_limit 0
                    194: do_test exclusive-2.6 {
                    195:   # Because connection 'db' only has a shared-lock, the other connection
                    196:   # will be able to get a RESERVED, but will fail to upgrade to EXCLUSIVE.
                    197:   execsql {
                    198:     BEGIN;
                    199:     INSERT INTO abc VALUES(7, 8, 9);
                    200:   } db2
                    201:   catchsql {
                    202:     COMMIT
                    203:   } db2
                    204: } {1 {database is locked}}
                    205: do_test exclusive-2.7 {
                    206:   catchsql {
                    207:     COMMIT
                    208:   } db2
                    209: } {1 {database is locked}}
                    210: do_test exclusive-2.8 {
                    211:   execsql {
                    212:     ROLLBACK;
                    213:   } db2
                    214: } {}
                    215: sqlite3_soft_heap_limit $cmdlinearg(soft-heap-limit)
                    216: 
                    217: do_test exclusive-2.9 {
                    218:   # Write the database to establish the exclusive lock with connection 'db.
                    219:   execsql {
                    220:     INSERT INTO abc VALUES(7, 8, 9);
                    221:   } db
                    222:   catchsql {
                    223:     SELECT * FROM abc;
                    224:   } db2
                    225: } {1 {database is locked}}
                    226: do_test exclusive-2.10 {
                    227:   # Changing the locking-mode does not release any locks.
                    228:   execsql {
                    229:     PRAGMA locking_mode = normal;
                    230:   } db
                    231:   catchsql {
                    232:     SELECT * FROM abc;
                    233:   } db2
                    234: } {1 {database is locked}}
                    235: do_test exclusive-2.11 {
                    236:   # After changing the locking mode, accessing the db releases locks.
                    237:   execsql {
                    238:     SELECT * FROM abc;
                    239:   } db
                    240:   execsql {
                    241:     SELECT * FROM abc;
                    242:   } db2
                    243: } {1 2 3 4 5 6 7 8 9}
                    244: db2 close
                    245: 
                    246: #----------------------------------------------------------------------
                    247: # Tests exclusive-3.X - test that a connection in exclusive mode 
                    248: # truncates instead of deletes the journal file when committing 
                    249: # a transaction.
                    250: #
                    251: # These tests are not run on windows because the windows backend
                    252: # opens the journal file for exclusive access, preventing its contents 
                    253: # from being inspected externally.
                    254: #
                    255: if {$tcl_platform(platform) != "windows"} {
                    256: 
                    257:   # Return a list of two booleans (either 0 or 1). The first is true
                    258:   # if the named file exists. The second is true only if the file
                    259:   # exists and the first 28 bytes contain at least one non-zero byte.
                    260:   #
                    261:   proc filestate {fname} {
                    262:     set exists 0
                    263:     set content 0
                    264:     if {[file exists $fname]} {
                    265:       set exists 1
                    266:       set hdr [hexio_read $fname 0 28]
                    267:       set content [expr {0==[string match $hdr [string repeat 0 56]]}]
                    268:     }
                    269:     list $exists $content
                    270:   }
                    271: 
                    272:   do_test exclusive-3.0 {
                    273:     filestate test.db-journal
                    274:   } {0 0}
                    275:   do_test exclusive-3.1 {
                    276:     execsql {
                    277:       PRAGMA locking_mode = exclusive;
                    278:       BEGIN;
                    279:       DELETE FROM abc;
                    280:     }
                    281:     filestate test.db-journal
                    282:   } {1 1}
                    283:   do_test exclusive-3.2 {
                    284:     execsql {
                    285:       COMMIT;
                    286:     }
                    287:     filestate test.db-journal
                    288:   } {1 0}
                    289:   do_test exclusive-3.3 {
                    290:     execsql {
                    291:       INSERT INTO abc VALUES('A', 'B', 'C');
                    292:       SELECT * FROM abc;
                    293:     }
                    294:   } {A B C}
                    295:   do_test exclusive-3.4 {
                    296:     execsql {
                    297:       BEGIN;
                    298:       UPDATE abc SET a = 1, b = 2, c = 3;
                    299:       ROLLBACK;
                    300:       SELECT * FROM abc;
                    301:     }
                    302:   } {A B C}
                    303:   do_test exclusive-3.5 {
                    304:     filestate test.db-journal
                    305:   } {1 0}
                    306:   do_test exclusive-3.6 {
                    307:     execsql {
                    308:       PRAGMA locking_mode = normal;
                    309:       SELECT * FROM abc;
                    310:     }
                    311:     filestate test.db-journal
                    312:   } {0 0}
                    313: }
                    314: 
                    315: #----------------------------------------------------------------------
                    316: # Tests exclusive-4.X - test that rollback works correctly when
                    317: # in exclusive-access mode.
                    318: #
                    319: 
                    320: # The following procedure computes a "signature" for table "t3".  If
                    321: # T3 changes in any way, the signature should change.  
                    322: #
                    323: # This is used to test ROLLBACK.  We gather a signature for t3, then
                    324: # make lots of changes to t3, then rollback and take another signature.
                    325: # The two signatures should be the same.
                    326: #
                    327: proc signature {} {
                    328:   return [db eval {SELECT count(*), md5sum(x) FROM t3}]
                    329: }
                    330: 
                    331: do_test exclusive-4.0 {
                    332:   execsql { PRAGMA locking_mode = exclusive; }
                    333:   execsql { PRAGMA default_cache_size = 10; }
                    334:   execsql {
                    335:     BEGIN;
                    336:     CREATE TABLE t3(x TEXT);
                    337:     INSERT INTO t3 VALUES(randstr(10,400));
                    338:     INSERT INTO t3 VALUES(randstr(10,400));
                    339:     INSERT INTO t3 SELECT randstr(10,400) FROM t3;
                    340:     INSERT INTO t3 SELECT randstr(10,400) FROM t3;
                    341:     INSERT INTO t3 SELECT randstr(10,400) FROM t3;
                    342:     INSERT INTO t3 SELECT randstr(10,400) FROM t3;
                    343:     COMMIT;
                    344:   }
                    345:   execsql {SELECT count(*) FROM t3;}
                    346: } {32}
                    347: 
                    348: set ::X [signature]
                    349: do_test exclusive-4.1 {
                    350:   execsql {
                    351:     BEGIN;
                    352:     DELETE FROM t3 WHERE random()%10!=0;
                    353:     INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
                    354:     INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
                    355:     SELECT count(*) FROM t3;
                    356:     ROLLBACK;
                    357:   }
                    358:   signature
                    359: } $::X
                    360: 
                    361: do_test exclusive-4.2 {
                    362:   execsql {
                    363:     BEGIN;
                    364:     DELETE FROM t3 WHERE random()%10!=0;
                    365:     INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
                    366:     DELETE FROM t3 WHERE random()%10!=0;
                    367:     INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
                    368:     ROLLBACK;
                    369:   }
                    370:   signature
                    371: } $::X
                    372: 
                    373: do_test exclusive-4.3 {
                    374:   execsql {
                    375:     INSERT INTO t3 SELECT randstr(10,400) FROM t3 WHERE random()%10==0;
                    376:   }
                    377: } {}
                    378: 
                    379: do_test exclusive-4.4 {
                    380:   catch {set ::X [signature]}
                    381: } {0}
                    382: do_test exclusive-4.5 {
                    383:   execsql {
                    384:     PRAGMA locking_mode = NORMAL;
                    385:     DROP TABLE t3;
                    386:     DROP TABLE abc;
                    387:   }
                    388: } {normal}
                    389: 
                    390: #----------------------------------------------------------------------
                    391: # Tests exclusive-5.X - test that statement journals are truncated
                    392: # instead of deleted when in exclusive access mode.
                    393: #
                    394: 
                    395: # Close and reopen the database so that the temp database is no
                    396: # longer active.
                    397: #
                    398: db close
                    399: sqlite3 db test.db
                    400: 
                    401: # if we're using proxy locks, we use 3 filedescriptors for a db
                    402: # that is open but NOT writing changes, normally
                    403: # sqlite uses 1 (proxy locking adds the conch and the local lock)
                    404: set using_proxy 0
                    405: foreach {name value} [array get env SQLITE_FORCE_PROXY_LOCKING] {
                    406:   set using_proxy $value
                    407: }
                    408: set extrafds 0
                    409: if {$using_proxy!=0} {
                    410:   set extrafds 2
                    411: } 
                    412: 
                    413: do_test exclusive-5.0 {
                    414:   execsql {
                    415:     CREATE TABLE abc(a UNIQUE, b UNIQUE, c UNIQUE);
                    416:     BEGIN;
                    417:     INSERT INTO abc VALUES(1, 2, 3);
                    418:     INSERT INTO abc SELECT a+1, b+1, c+1 FROM abc;
                    419:   }
                    420: } {}
                    421: do_test exclusive-5.1 {
                    422:   # Three files are open: The db, journal and statement-journal.
                    423:   set sqlite_open_file_count
                    424:   expr $sqlite_open_file_count-$extrafds
                    425: } [expr 3 - ($TEMP_STORE>=2)]
                    426: do_test exclusive-5.2 {
                    427:   execsql {
                    428:     COMMIT;
                    429:   }
                    430:   # One file open: the db.
                    431:   set sqlite_open_file_count
                    432:   expr $sqlite_open_file_count-$extrafds
                    433: } {1}
                    434: do_test exclusive-5.3 {
                    435:   execsql {
                    436:     PRAGMA locking_mode = exclusive;
                    437:     BEGIN;
                    438:     INSERT INTO abc VALUES(5, 6, 7);
                    439:   }
                    440:   # Two files open: the db and journal.
                    441:   set sqlite_open_file_count
                    442:   expr $sqlite_open_file_count-$extrafds
                    443: } {2}
                    444: do_test exclusive-5.4 {
                    445:   execsql {
                    446:     INSERT INTO abc SELECT a+10, b+10, c+10 FROM abc;
                    447:   }
                    448:   # Three files are open: The db, journal and statement-journal.
                    449:   set sqlite_open_file_count
                    450:   expr $sqlite_open_file_count-$extrafds
                    451: } [expr 3 - ($TEMP_STORE>=2)]
                    452: do_test exclusive-5.5 {
                    453:   execsql {
                    454:     COMMIT;
                    455:   }
                    456:   # Three files are still open: The db, journal and statement-journal.
                    457:   set sqlite_open_file_count
                    458:   expr $sqlite_open_file_count-$extrafds
                    459: } [expr 3 - ($TEMP_STORE>=2)]
                    460: do_test exclusive-5.6 {
                    461:   execsql {
                    462:     PRAGMA locking_mode = normal;
                    463:     SELECT * FROM abc;
                    464:   }
                    465: } {normal 1 2 3 2 3 4 5 6 7 11 12 13 12 13 14 15 16 17}
                    466: do_test exclusive-5.7 {
                    467:   # Just the db open.
                    468:   set sqlite_open_file_count
                    469:   expr $sqlite_open_file_count-$extrafds
                    470: } {1}
                    471: 
                    472: #-------------------------------------------------------------------------
                    473: 
                    474: do_execsql_test exclusive-6.1 {
                    475:   CREATE TABLE t4(a, b);
                    476:   INSERT INTO t4 VALUES('Eden', 1955);
                    477:   BEGIN;
                    478:     INSERT INTO t4 VALUES('Macmillan', 1957);
                    479:     INSERT INTO t4 VALUES('Douglas-Home', 1963);
                    480:     INSERT INTO t4 VALUES('Wilson', 1964);
                    481: }
                    482: do_test exclusive-6.2 {
                    483:   forcedelete test2.db test2.db-journal
                    484:   copy_file test.db test2.db
                    485:   copy_file test.db-journal test2.db-journal
                    486:   sqlite3 db test2.db
                    487: } {}
                    488: 
                    489: do_execsql_test exclusive-6.3 {
                    490:   PRAGMA locking_mode = EXCLUSIVE;
                    491:   SELECT * FROM t4;
                    492: } {exclusive Eden 1955}
                    493: 
                    494: do_test exclusive-6.4 {
                    495:   db close
                    496:   forcedelete test.db test.db-journal
                    497:   set fd [open test.db-journal w]
                    498:   puts $fd x
                    499:   close $fd
                    500:   sqlite3 db test.db
                    501: } {}
                    502: 
                    503: do_execsql_test exclusive-6.5 {
                    504:   PRAGMA locking_mode = EXCLUSIVE;
                    505:   SELECT * FROM sqlite_master;
                    506: } {exclusive}
                    507: 
                    508: finish_test
                    509: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>