summaryrefslogtreecommitdiffstats
path: root/qa/workunits/rados/test_libcephsqlite.sh
blob: 1810a3f3f72a2caefe486dfdf8c5b93a642f0ee9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#!/bin/bash -ex

# The main point of these tests beyond ceph_test_libcephsqlite is to:
#
# - Ensure you can load the Ceph VFS via the dynamic load extension mechanism
#   in SQLite.
# - Check the behavior of a dead application, that it does not hold locks
#   indefinitely.

pool="$1"
ns="$(basename $0)"

function sqlite {
  background="$1"
  if [ "$background" = b ]; then
    shift
  fi
  a=$(cat)
  printf "%s" "$a" >&2
  # We're doing job control gymnastics here to make sure that sqlite3 is the
  # main process (i.e. the process group leader) in the background, not a bash
  # function or job pipeline.
  sqlite3 -cmd '.output /dev/null' -cmd '.load libcephsqlite.so' -cmd 'pragma journal_mode = PERSIST' -cmd ".open file:///$pool:$ns/baz.db?vfs=ceph" -cmd '.output stdout' <<<"$a" &
  if [ "$background" != b ]; then
    wait
  fi
}

function striper {
  rados --pool=$pool --namespace="$ns" --striper "$@"
}

function repeat {
  n=$1
  shift
  for ((i = 0; i < "$n"; ++i)); do
    echo "$*"
  done
}

striper rm baz.db || true

time sqlite <<EOF
create table if not exists foo (a INT);
insert into foo (a) values (RANDOM());
drop table foo;
EOF

striper stat baz.db
striper rm baz.db

time sqlite <<EOF
CREATE TABLE IF NOT EXISTS rand(text BLOB NOT NULL);
$(repeat 10 'INSERT INTO rand (text) VALUES (RANDOMBLOB(4096));')
SELECT LENGTH(text) FROM rand;
DROP TABLE rand;
EOF

time sqlite <<EOF
BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS rand(text BLOB NOT NULL);
$(repeat 100 'INSERT INTO rand (text) VALUES (RANDOMBLOB(4096));')
COMMIT;
SELECT LENGTH(text) FROM rand;
DROP TABLE rand;
EOF

# Connection death drops the lock:

striper rm baz.db
date
sqlite b <<EOF
CREATE TABLE foo (a BLOB);
INSERT INTO foo VALUES ("start");
WITH RECURSIVE c(x) AS
  (
   VALUES(1)
  UNION ALL
   SELECT x+1
   FROM c
  )
INSERT INTO foo (a)
  SELECT RANDOMBLOB(1<<20)
  FROM c
  LIMIT (1<<20);
EOF

# Let it chew on that INSERT for a while so it writes data, it will not finish as it's trying to write 2^40 bytes...
sleep 10
echo done

jobs -l
kill -KILL -- $(jobs -p)
date
wait
date

n=$(sqlite <<<"SELECT COUNT(*) FROM foo;")
[ "$n" -eq 1 ]

# Connection "hang" loses the lock and cannot reacquire it:

striper rm baz.db
date
sqlite b <<EOF
CREATE TABLE foo (a BLOB);
INSERT INTO foo VALUES ("start");
WITH RECURSIVE c(x) AS
  (
   VALUES(1)
  UNION ALL
   SELECT x+1
   FROM c
  )
INSERT INTO foo (a)
  SELECT RANDOMBLOB(1<<20)
  FROM c
  LIMIT (1<<20);
EOF

# Same thing, let it chew on the INSERT for a while...
sleep 20
jobs -l
kill -STOP -- $(jobs -p)
# cephsqlite_lock_renewal_timeout is 30s
sleep 45
date
kill -CONT -- $(jobs -p)
sleep 10
date
# it should exit with an error as it lost the lock
wait
date

n=$(sqlite <<<"SELECT COUNT(*) FROM foo;")
[ "$n" -eq 1 ]