Annotation of embedaddon/sqlite3/test/exclusive.test, revision 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>