sqlite/ext/session/session5.test
dan 1756ae10e1 Add tests and fixes for OOM handling in sqlite3changeset_concat().
FossilOrigin-Name: df0b2d21dcd81679e55b24866f97568019932983
2011-04-15 16:03:32 +00:00

248 lines
6.0 KiB
Plaintext

# 2011 April 13
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for the session module.
# Specifically, for the sqlite3changeset_concat() command.
#
if {![info exists testdir]} {
set testdir [file join [file dirname [info script]] .. .. test]
}
source [file join [file dirname [info script]] session_common.tcl]
source $testdir/tester.tcl
ifcapable !session {finish_test; return}
set testprefix session5
# Organization of tests:
#
# session5-1.*: Simple tests to check the concat() function produces
# correct results.
#
# session5-2.*: More complicated tests.
#
# session5-3.*: Schema mismatch errors.
#
proc do_concat_test {tn args} {
set subtest 0
foreach sql $args {
incr subtest
sqlite3session S db main ; S attach *
execsql $sql
set c [S changeset]
if {[info commands s_prev] != ""} {
set c_concat [sqlite3changeset_concat $c_prev $c]
set c_two [s_prev changeset]
s_prev delete
set h_concat [changeset_to_list $c_concat]
set h_two [changeset_to_list $c_two]
do_test $tn.$subtest [list set {} $h_concat] $h_two
}
set c_prev $c
rename S s_prev
}
catch { s_prev delete }
}
#-------------------------------------------------------------------------
# Test cases session5-1.* - simple tests.
#
do_execsql_test 1.0 {
CREATE TABLE t1(a PRIMARY KEY, b);
}
do_concat_test 1.1.1 {
INSERT INTO t1 VALUES(1, 'one');
} {
INSERT INTO t1 VALUES(2, 'two');
}
do_concat_test 1.1.2 {
UPDATE t1 SET b = 'five' WHERE a = 1;
} {
UPDATE t1 SET b = 'six' WHERE a = 2;
}
do_concat_test 1.1.3 {
DELETE FROM t1 WHERE a = 1;
} {
DELETE FROM t1 WHERE a = 2;
}
# 1.2.1: INSERT + DELETE -> (none)
# 1.2.2: INSERT + UPDATE -> INSERT
#
# 1.2.3: DELETE + INSERT (matching data) -> (none)
# 1.2.4: DELETE + INSERT (non-matching data) -> UPDATE
#
# 1.2.5: UPDATE + UPDATE (matching data) -> (none)
# 1.2.6: UPDATE + UPDATE (non-matching data) -> UPDATE
# 1.2.7: UPDATE + DELETE -> DELETE
#
do_concat_test 1.2.1 {
INSERT INTO t1 VALUES('x', 'y');
} {
DELETE FROM t1 WHERE a = 'x';
}
do_concat_test 1.2.2 {
INSERT INTO t1 VALUES(5.0, 'five');
} {
UPDATE t1 SET b = 'six' WHERE a = 5.0;
}
do_execsql_test 1.2.3.1 "INSERT INTO t1 VALUES('I', 'one')"
do_concat_test 1.2.3.2 {
DELETE FROM t1 WHERE a = 'I';
} {
INSERT INTO t1 VALUES('I', 'one');
}
do_concat_test 1.2.4 {
DELETE FROM t1 WHERE a = 'I';
} {
INSERT INTO t1 VALUES('I', 'two');
}
do_concat_test 1.2.5 {
UPDATE t1 SET b = 'five' WHERE a = 'I';
} {
UPDATE t1 SET b = 'two' WHERE a = 'I';
}
do_concat_test 1.2.6 {
UPDATE t1 SET b = 'six' WHERE a = 'I';
} {
UPDATE t1 SET b = 'seven' WHERE a = 'I';
}
do_concat_test 1.2.7 {
UPDATE t1 SET b = 'eight' WHERE a = 'I';
} {
DELETE FROM t1 WHERE a = 'I';
}
#-------------------------------------------------------------------------
# Test cases session5-2.* - more complex tests.
#
db function indirect indirect
proc indirect {{x -1}} {
S indirect $x
s_prev indirect $x
}
do_concat_test 2.1 {
CREATE TABLE abc(a, b, c PRIMARY KEY);
INSERT INTO abc VALUES(NULL, NULL, 1);
INSERT INTO abc VALUES('abcdefghijkl', NULL, 2);
} {
DELETE FROM abc WHERE c = 1;
UPDATE abc SET c = 1 WHERE c = 2;
} {
INSERT INTO abc VALUES('abcdefghijkl', NULL, 2);
INSERT INTO abc VALUES(1.0, 2.0, 3);
} {
UPDATE abc SET a = a-1;
} {
CREATE TABLE def(d, e, f, PRIMARY KEY(e, f));
INSERT INTO def VALUES('x', randomblob(11000), 67);
INSERT INTO def SELECT d, e, f+1 FROM def;
INSERT INTO def SELECT d, e, f+2 FROM def;
INSERT INTO def SELECT d, e, f+4 FROM def;
} {
DELETE FROM def WHERE rowid>4;
} {
INSERT INTO def SELECT d, e, f+4 FROM def;
} {
INSERT INTO abc VALUES(22, 44, -1);
} {
UPDATE abc SET c=-2 WHERE c=-1;
UPDATE abc SET c=-3 WHERE c=-2;
} {
UPDATE abc SET c=-4 WHERE c=-3;
} {
UPDATE abc SET a=a+1 WHERE c=-3;
UPDATE abc SET a=a+1 WHERE c=-3;
} {
UPDATE abc SET a=a+1 WHERE c=-3;
UPDATE abc SET a=a+1 WHERE c=-3;
} {
INSERT INTO abc VALUES('one', 'two', 'three');
} {
SELECT indirect(1);
UPDATE abc SET a='one point five' WHERE c = 'three';
} {
SELECT indirect(0);
UPDATE abc SET a='one point six' WHERE c = 'three';
}
catch {db close}
forcedelete test.db
sqlite3 db test.db
do_concat_test 2.2 {
CREATE TABLE t1(a, b, PRIMARY KEY(b));
CREATE TABLE t2(a PRIMARY KEY, b);
INSERT INTO t1 VALUES('string', 1);
INSERT INTO t1 VALUES(4, 2);
INSERT INTO t1 VALUES(X'FFAAFFAAFFAA', 3);
} {
INSERT INTO t2 VALUES('one', 'two');
INSERT INTO t2 VALUES(1, NULL);
UPDATE t1 SET a = 5 WHERE a = 2;
} {
DELETE FROM t2 WHERE a = 1;
UPDATE t1 SET a = 4 WHERE a = 2;
INSERT INTO t2 VALUES('x', 'y');
}
#-------------------------------------------------------------------------
# Test that schema incompatibilities are detected correctly.
#
# session5-3.1: Incompatible number of columns.
# session5-3.2: Incompatible PK definition.
#
do_test 3.1 {
db close
forcedelete test.db
sqlite3 db test.db
execsql { CREATE TABLE t1(a PRIMARY KEY, b) }
set c1 [changeset_from_sql { INSERT INTO t1 VALUES(1, 2) }]
execsql {
DROP TABLE t1;
CREATE TABLE t1(a PRIMARY KEY, b, c);
}
set c2 [changeset_from_sql { INSERT INTO t1 VALUES(2, 3, 4) }]
list [catch { sqlite3changeset_concat $c1 $c2 } msg] $msg
} {1 SQLITE_SCHEMA}
do_test 3.2 {
db close
forcedelete test.db
sqlite3 db test.db
execsql { CREATE TABLE t1(a PRIMARY KEY, b) }
set c1 [changeset_from_sql { INSERT INTO t1 VALUES(1, 2) }]
execsql {
DROP TABLE t1;
CREATE TABLE t1(a, b PRIMARY KEY);
}
set c2 [changeset_from_sql { INSERT INTO t1 VALUES(2, 3) }]
list [catch { sqlite3changeset_concat $c1 $c2 } msg] $msg
} {1 SQLITE_SCHEMA}
finish_test