extralite 3.1.3 → 3.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/test-asan.yml +37 -0
- data/.gitignore +1 -1
- data/CHANGELOG.md +4 -0
- data/Rakefile +32 -0
- data/ext/extralite/database.c +8 -5
- data/ext/extralite/extconf-bundle.rb +18 -0
- data/ext/extralite/extconf.rb +15 -0
- data/ext/extralite/iterator.c +1 -1
- data/ext/extralite/query.c +1 -1
- data/lib/extralite/version.rb +1 -1
- data/lib/extralite.rb +1 -1
- data/test/helper.rb +37 -0
- data/test/test_database.rb +23 -17
- data/test/test_iterator.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5281aeb88afdc13d5ab8997ef3d268b5c2f23bba5c10121d82d93fa1b0c6683e
|
|
4
|
+
data.tar.gz: 98c7ebcc643f1c228e7dd154530363d2b590c32e8c6ec2048ab680e6ef8dff29
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 500b76bae6913d602bfea5a611e0dab55a36563b665afc9ad48143c379cd6c7cfffa768a35dfaec966286197dbc1e1bdf02a4d7203bab6f3adf4b10c14ff92e3
|
|
7
|
+
data.tar.gz: d93b59540dfd75a7ddb1d0477e48cf064d49e1c8800f18b7953f7a04e58a756c48f6e3dac71e6d3d8df4463faa3a573aafb942bbf3e93170a630e5dcaf9dad12
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
name: Tests (AddressSanitizer)
|
|
2
|
+
|
|
3
|
+
on: [push, pull_request]
|
|
4
|
+
|
|
5
|
+
concurrency:
|
|
6
|
+
group: tests-${{ format('{0}-{1}', github.head_ref || github.run_number, github.job) }}
|
|
7
|
+
cancel-in-progress: true
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
asan:
|
|
11
|
+
strategy:
|
|
12
|
+
fail-fast: false
|
|
13
|
+
matrix:
|
|
14
|
+
include:
|
|
15
|
+
# Ruby is not instrumented, rake test:asan preloads libasan
|
|
16
|
+
- { ruby: '3.4', os: ubuntu-latest, test_task: 'test:asan' }
|
|
17
|
+
- { ruby: '4.0', os: ubuntu-latest, test_task: 'test:asan' }
|
|
18
|
+
# Ruby built with ASan (latest stable release), only on ubuntu-24.04
|
|
19
|
+
- { ruby: 'asan-release', os: ubuntu-24.04, test_task: 'test' }
|
|
20
|
+
|
|
21
|
+
name: ASan, ${{matrix.ruby}}
|
|
22
|
+
|
|
23
|
+
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
|
|
24
|
+
|
|
25
|
+
runs-on: ${{matrix.os}}
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v4
|
|
28
|
+
- uses: ruby/setup-ruby@v1
|
|
29
|
+
with:
|
|
30
|
+
ruby-version: ${{matrix.ruby}}
|
|
31
|
+
bundler-cache: true
|
|
32
|
+
- name: Compile C-extension with ASan (bundled SQLite)
|
|
33
|
+
run: EXTRALITE_BUNDLE=1 EXTRALITE_ASAN=1 bundle exec rake compile
|
|
34
|
+
- name: Run tests
|
|
35
|
+
run: bundle exec rake ${{matrix.test_task}}
|
|
36
|
+
- name: Run tests with GC.stress
|
|
37
|
+
run: EXTRALITE_GC_STRESS=1 bundle exec rake ${{matrix.test_task}}
|
data/.gitignore
CHANGED
|
@@ -51,7 +51,7 @@ build-iPhoneSimulator/
|
|
|
51
51
|
# for a library or gem, you might want to ignore these files since the code is
|
|
52
52
|
# intended to run in multiple environments; otherwise, check them in:
|
|
53
53
|
# Gemfile.lock
|
|
54
|
-
|
|
54
|
+
.ruby-version
|
|
55
55
|
# .ruby-gemset
|
|
56
56
|
|
|
57
57
|
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
data/CHANGELOG.md
CHANGED
data/Rakefile
CHANGED
|
@@ -15,6 +15,38 @@ task :test do
|
|
|
15
15
|
exec 'ruby test/run.rb'
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
+
namespace :test do
|
|
19
|
+
# Runs the tests against an extension built with AddressSanitizer:
|
|
20
|
+
#
|
|
21
|
+
# bundle exec rake clean
|
|
22
|
+
# EXTRALITE_BUNDLE=1 EXTRALITE_ASAN=1 bundle exec rake compile
|
|
23
|
+
# bundle exec rake test:asan
|
|
24
|
+
#
|
|
25
|
+
# Set TEST_FILES (comma separated) to run only some test files.
|
|
26
|
+
#
|
|
27
|
+
# Ruby itself is not built with ASan, so libasan has to be preloaded.
|
|
28
|
+
# use_sigaltstack=0: Ruby installs its own signal stack for each thread,
|
|
29
|
+
# which makes ASan fail when it unmaps its own signal stack on thread exit.
|
|
30
|
+
# Leak detection is off because Ruby does not free everything on exit.
|
|
31
|
+
desc 'Run tests with an ASan build of the extension (Linux only)'
|
|
32
|
+
task :asan do
|
|
33
|
+
so = Dir['lib/extralite_ext.{so,bundle}'].first
|
|
34
|
+
libasan = so && `ldd #{so}`[/^\s*libasan\S*\s*=>\s*(\S+)/, 1]
|
|
35
|
+
abort 'The extension is not built with EXTRALITE_ASAN=1' unless libasan
|
|
36
|
+
|
|
37
|
+
env = {
|
|
38
|
+
'LD_PRELOAD' => libasan,
|
|
39
|
+
'ASAN_OPTIONS' => "detect_leaks=0:use_sigaltstack=0:abort_on_error=1:#{ENV['ASAN_OPTIONS']}"
|
|
40
|
+
}
|
|
41
|
+
files = ENV['TEST_FILES']&.split(',')
|
|
42
|
+
if files
|
|
43
|
+
exec env, 'ruby', '-Itest', '-e', files.map { "require './#{it}'" }.join(';')
|
|
44
|
+
else
|
|
45
|
+
exec env, 'ruby test/run.rb'
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
18
50
|
CLEAN.include 'lib/*.o', 'lib/*.so', 'lib/*.so.*', 'lib/*.a', 'lib/*.bundle', 'lib/*.jar', 'pkg', 'tmp'
|
|
19
51
|
|
|
20
52
|
require 'yard'
|
data/ext/extralite/database.c
CHANGED
|
@@ -237,11 +237,12 @@ VALUE Database_initialize(int argc, VALUE *argv, VALUE self) {
|
|
|
237
237
|
sqlite3_db_config(db->sqlite3_db ,SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 1, NULL);
|
|
238
238
|
#endif
|
|
239
239
|
|
|
240
|
-
db->stmt_cache
|
|
240
|
+
RB_OBJ_WRITE(self, &db->stmt_cache, rb_hash_new());
|
|
241
241
|
db->trace_proc = Qnil;
|
|
242
242
|
db->gvl_release_threshold = DEFAULT_GVL_RELEASE_THRESHOLD;
|
|
243
243
|
|
|
244
244
|
db->progress_handler = global_progress_handler;
|
|
245
|
+
RB_OBJ_WRITTEN(self, Qundef, db->progress_handler.proc);
|
|
245
246
|
db->progress_handler.tick_count = 0;
|
|
246
247
|
db->progress_handler.call_count = 0;
|
|
247
248
|
if (db->progress_handler.mode != PROGRESS_NONE) {
|
|
@@ -627,7 +628,7 @@ VALUE Database_batch_query(VALUE self, VALUE sql, VALUE parameters) {
|
|
|
627
628
|
sqlite3_stmt *stmt;
|
|
628
629
|
|
|
629
630
|
stmt_ctx stmt_ctx;
|
|
630
|
-
make_stmt_ctx(&stmt_ctx, db, &stmt, sql, RARRAY_LEN(parameters), NULL);
|
|
631
|
+
make_stmt_ctx(&stmt_ctx, db, &stmt, sql, (TYPE(parameters) == T_ARRAY) ? RARRAY_LEN(parameters) : 0, NULL);
|
|
631
632
|
prep_single_stmt(&stmt_ctx);
|
|
632
633
|
// prepare_xsingle_stmt(DB_GVL_MODE(db), db->stmt_cache, db->sqlite3_db, &stmt, sql, 0, NULL);
|
|
633
634
|
query_ctx ctx = QUERY_CTX(
|
|
@@ -664,7 +665,7 @@ VALUE Database_batch_query_array(VALUE self, VALUE sql, VALUE parameters) {
|
|
|
664
665
|
sqlite3_stmt *stmt;
|
|
665
666
|
|
|
666
667
|
stmt_ctx stmt_ctx;
|
|
667
|
-
make_stmt_ctx(&stmt_ctx, db, &stmt, sql, RARRAY_LEN(parameters), NULL);
|
|
668
|
+
make_stmt_ctx(&stmt_ctx, db, &stmt, sql, (TYPE(parameters) == T_ARRAY) ? RARRAY_LEN(parameters) : 0, NULL);
|
|
668
669
|
prep_single_stmt(&stmt_ctx);
|
|
669
670
|
// prepare_xsingle_stmt(DB_GVL_MODE(db), db->stmt_cache, db->sqlite3_db, &stmt, sql, 0, NULL);
|
|
670
671
|
query_ctx ctx = QUERY_CTX(
|
|
@@ -701,7 +702,7 @@ VALUE Database_batch_query_splat(VALUE self, VALUE sql, VALUE parameters) {
|
|
|
701
702
|
sqlite3_stmt *stmt;
|
|
702
703
|
|
|
703
704
|
stmt_ctx stmt_ctx;
|
|
704
|
-
make_stmt_ctx(&stmt_ctx, db, &stmt, sql, RARRAY_LEN(parameters), NULL);
|
|
705
|
+
make_stmt_ctx(&stmt_ctx, db, &stmt, sql, (TYPE(parameters) == T_ARRAY) ? RARRAY_LEN(parameters) : 0, NULL);
|
|
705
706
|
prep_single_stmt(&stmt_ctx);
|
|
706
707
|
// prepare_xsingle_stmt(DB_GVL_MODE(db), db->stmt_cache, db->sqlite3_db, &stmt, sql, 0, NULL);
|
|
707
708
|
query_ctx ctx = QUERY_CTX(
|
|
@@ -1736,7 +1737,9 @@ void Init_ExtraliteDatabase(void) {
|
|
|
1736
1737
|
rb_gc_register_mark_object(SYM_truncate);
|
|
1737
1738
|
rb_gc_register_mark_object(SYM_wal);
|
|
1738
1739
|
|
|
1739
|
-
|
|
1740
|
+
// the proc is replaced by Extralite.on_progress, so register the address,
|
|
1741
|
+
// not the current value
|
|
1742
|
+
rb_gc_register_address(&global_progress_handler.proc);
|
|
1740
1743
|
|
|
1741
1744
|
UTF8_ENCODING = rb_utf8_encoding();
|
|
1742
1745
|
}
|
|
@@ -6,6 +6,24 @@ $CFLAGS << ' -Wno-undef'
|
|
|
6
6
|
$CFLAGS << ' -Wno-discarded-qualifiers'
|
|
7
7
|
$CFLAGS << ' -Wno-unused-function'
|
|
8
8
|
|
|
9
|
+
# Development only: build with AddressSanitizer (EXTRALITE_ASAN=1), then run
|
|
10
|
+
# the tests with `bundle exec rake test:asan` (see Rakefile).
|
|
11
|
+
#
|
|
12
|
+
# -fgnu89-inline: several non-static functions in the C files are declared
|
|
13
|
+
# `inline` without an extern definition, which only links when every call is
|
|
14
|
+
# inlined (as with the default -O3).
|
|
15
|
+
if ENV['EXTRALITE_ASAN']
|
|
16
|
+
$CFLAGS << ' -fsanitize=address -fno-omit-frame-pointer -O1 -g -fgnu89-inline'
|
|
17
|
+
$LDFLAGS << ' -fsanitize=address'
|
|
18
|
+
# No stack instrumentation: Ruby raises exceptions with longjmp, which
|
|
19
|
+
# leaves poisoned stack redzones behind and causes false reports later.
|
|
20
|
+
# It also keeps local VALUEs on the real stack, where the GC can see them.
|
|
21
|
+
$CFLAGS << (try_cflags('--param=asan-stack=0') ? ' --param=asan-stack=0' : ' -mllvm -asan-stack=0')
|
|
22
|
+
# SQLite serves small allocations (including statements) from its own
|
|
23
|
+
# lookaside pool, which hides use-after-free bugs from ASan.
|
|
24
|
+
$defs << '-DSQLITE_DEFAULT_LOOKASIDE=0,0'
|
|
25
|
+
end
|
|
26
|
+
|
|
9
27
|
# enable the session extension
|
|
10
28
|
$defs << '-DSQLITE_ENABLE_SESSION'
|
|
11
29
|
$defs << '-DSQLITE_ENABLE_PREUPDATE_HOOK'
|
data/ext/extralite/extconf.rb
CHANGED
|
@@ -48,6 +48,21 @@ else
|
|
|
48
48
|
dir_config('sqlite3', cppflags, ldflags)
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
+
# Development only: build with AddressSanitizer (EXTRALITE_ASAN=1), then run
|
|
52
|
+
# the tests with `bundle exec rake test:asan` (see Rakefile).
|
|
53
|
+
#
|
|
54
|
+
# -fgnu89-inline: several non-static functions in the C files are declared
|
|
55
|
+
# `inline` without an extern definition, which only links when every call is
|
|
56
|
+
# inlined (as with the default -O3).
|
|
57
|
+
if ENV['EXTRALITE_ASAN']
|
|
58
|
+
$CFLAGS << ' -fsanitize=address -fno-omit-frame-pointer -O1 -g -fgnu89-inline'
|
|
59
|
+
$LDFLAGS << ' -fsanitize=address'
|
|
60
|
+
# No stack instrumentation: Ruby raises exceptions with longjmp, which
|
|
61
|
+
# leaves poisoned stack redzones behind and causes false reports later.
|
|
62
|
+
# It also keeps local VALUEs on the real stack, where the GC can see them.
|
|
63
|
+
$CFLAGS << (try_cflags('--param=asan-stack=0') ? ' --param=asan-stack=0' : ' -mllvm -asan-stack=0')
|
|
64
|
+
end
|
|
65
|
+
|
|
51
66
|
if RbConfig::CONFIG['host_os'] =~ /mswin/
|
|
52
67
|
$CFLAGS << ' -W3'
|
|
53
68
|
end
|
data/ext/extralite/iterator.c
CHANGED
|
@@ -54,7 +54,7 @@ static inline Iterator_t *self_to_iterator(VALUE obj) {
|
|
|
54
54
|
*/
|
|
55
55
|
VALUE Iterator_initialize(VALUE self, VALUE query) {
|
|
56
56
|
Iterator_t *iterator = self_to_iterator(self);
|
|
57
|
-
iterator->query
|
|
57
|
+
RB_OBJ_WRITE(self, &iterator->query, query);
|
|
58
58
|
return Qnil;
|
|
59
59
|
}
|
|
60
60
|
|
data/ext/extralite/query.c
CHANGED
|
@@ -649,7 +649,7 @@ VALUE Query_transform_get(VALUE self) {
|
|
|
649
649
|
*/
|
|
650
650
|
VALUE Query_transform_set(VALUE self, VALUE transform) {
|
|
651
651
|
Query_t *query = self_to_query(self);
|
|
652
|
-
query->transform
|
|
652
|
+
RB_OBJ_WRITE(self, &query->transform, transform);
|
|
653
653
|
query->transform_object = rb_obj_is_instance_of(transform, cTransform);
|
|
654
654
|
return self;
|
|
655
655
|
}
|
data/lib/extralite/version.rb
CHANGED
data/lib/extralite.rb
CHANGED
data/test/helper.rb
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require 'bundler/setup'
|
|
4
4
|
require 'extralite'
|
|
5
5
|
require 'minitest/autorun'
|
|
6
|
+
require 'tempfile'
|
|
6
7
|
|
|
7
8
|
puts "sqlite3 version: #{Extralite.sqlite3_version}"
|
|
8
9
|
|
|
@@ -22,7 +23,43 @@ module TestExtensions
|
|
|
22
23
|
@db = nil
|
|
23
24
|
GC.start
|
|
24
25
|
super
|
|
26
|
+
ensure
|
|
27
|
+
@tempfiles&.each(&:close!)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Returns the path of a new temp file. The Tempfile is kept until teardown,
|
|
31
|
+
# otherwise GC may delete the file while a database is still using it.
|
|
32
|
+
def tempfile_path(name)
|
|
33
|
+
(@tempfiles ||= []) << (tmp = Tempfile.new(name))
|
|
34
|
+
tmp.path
|
|
25
35
|
end
|
|
26
36
|
end
|
|
27
37
|
|
|
28
38
|
Minitest::Test.prepend(TestExtensions)
|
|
39
|
+
|
|
40
|
+
# EXTRALITE_GC_STRESS=1 runs every test with GC.stress enabled, which makes GC
|
|
41
|
+
# bugs in the C extension (objects freed too early, wrong free order) show up
|
|
42
|
+
# reliably. It's slow, so you may want to run only some test files, e.g.:
|
|
43
|
+
#
|
|
44
|
+
# EXTRALITE_GC_STRESS=1 ruby test/test_stmt_cache.rb
|
|
45
|
+
if ENV['EXTRALITE_GC_STRESS']
|
|
46
|
+
module GCStressExtensions
|
|
47
|
+
def before_setup
|
|
48
|
+
super
|
|
49
|
+
GC.stress = true
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def after_teardown
|
|
53
|
+
GC.stress = false
|
|
54
|
+
super
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
Minitest::Test.prepend(GCStressExtensions)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
module Minitest::Assertions
|
|
62
|
+
def skip_with_gc_stress
|
|
63
|
+
skip 'timing-sensitive, too slow with GC.stress' if ENV['EXTRALITE_GC_STRESS']
|
|
64
|
+
end
|
|
65
|
+
end
|
data/test/test_database.rb
CHANGED
|
@@ -347,7 +347,7 @@ class DatabaseTest < Minitest::Test
|
|
|
347
347
|
|
|
348
348
|
assert_raises { @db.tables('foo') }
|
|
349
349
|
|
|
350
|
-
fn =
|
|
350
|
+
fn = tempfile_path('extralite_test_tables_with_db_name')
|
|
351
351
|
@db.execute "attach database '#{fn}' as foo"
|
|
352
352
|
|
|
353
353
|
assert_equal [], @db.tables('foo')
|
|
@@ -382,7 +382,7 @@ class DatabaseTest < Minitest::Test
|
|
|
382
382
|
end
|
|
383
383
|
|
|
384
384
|
def test_integrity_check_damaged
|
|
385
|
-
fn =
|
|
385
|
+
fn = tempfile_path('extralite_test_integrity_check_damaged')
|
|
386
386
|
db = Extralite::Database.new(fn)
|
|
387
387
|
|
|
388
388
|
db.execute <<~SQL
|
|
@@ -422,7 +422,7 @@ class DatabaseTest < Minitest::Test
|
|
|
422
422
|
end
|
|
423
423
|
|
|
424
424
|
def test_quick_check_damaged
|
|
425
|
-
fn =
|
|
425
|
+
fn = tempfile_path('extralite_test_quick_check_damaged')
|
|
426
426
|
db = Extralite::Database.new(fn)
|
|
427
427
|
|
|
428
428
|
db.execute <<~SQL
|
|
@@ -882,7 +882,8 @@ class DatabaseTest < Minitest::Test
|
|
|
882
882
|
end
|
|
883
883
|
|
|
884
884
|
def test_database_busy_timeout
|
|
885
|
-
|
|
885
|
+
skip_with_gc_stress
|
|
886
|
+
fn = tempfile_path('extralite_test_database_busy_timeout')
|
|
886
887
|
db1 = Extralite::Database.new(fn)
|
|
887
888
|
db2 = Extralite::Database.new(fn)
|
|
888
889
|
|
|
@@ -978,13 +979,13 @@ class DatabaseTest < Minitest::Test
|
|
|
978
979
|
db = Extralite::Database.new(':memory:', gvl_release_threshold: 23)
|
|
979
980
|
assert_equal 23, db.gvl_release_threshold
|
|
980
981
|
|
|
981
|
-
fn =
|
|
982
|
+
fn = tempfile_path('extralite_test_database_initialize_modern')
|
|
982
983
|
db = Extralite::Database.new(fn)
|
|
983
984
|
assert_equal 'wal', db.pragma(:journal_mode)
|
|
984
985
|
assert_equal 1, db.pragma(:synchronous)
|
|
985
986
|
assert_equal 1, db.pragma(:foreign_keys)
|
|
986
987
|
|
|
987
|
-
fn =
|
|
988
|
+
fn = tempfile_path('extralite_test_database_initialize_legacy')
|
|
988
989
|
db = Extralite::Database.new(fn, legacy: true)
|
|
989
990
|
assert_equal 'delete', db.pragma(:journal_mode)
|
|
990
991
|
assert_equal 2, db.pragma(:synchronous)
|
|
@@ -1011,7 +1012,7 @@ class DatabaseTest < Minitest::Test
|
|
|
1011
1012
|
end
|
|
1012
1013
|
|
|
1013
1014
|
def test_database_transaction_commit
|
|
1014
|
-
path =
|
|
1015
|
+
path = tempfile_path('extralite_test_database_transaction_commit')
|
|
1015
1016
|
db1 = Extralite::Database.new(path)
|
|
1016
1017
|
db2 = Extralite::Database.new(path)
|
|
1017
1018
|
|
|
@@ -1165,7 +1166,7 @@ class DatabaseTest < Minitest::Test
|
|
|
1165
1166
|
end
|
|
1166
1167
|
|
|
1167
1168
|
def test_wal_checkpoint
|
|
1168
|
-
fn =
|
|
1169
|
+
fn = tempfile_path('extralite_test_wal_checkpoint')
|
|
1169
1170
|
|
|
1170
1171
|
db = Extralite::Database.new(fn)
|
|
1171
1172
|
|
|
@@ -1258,7 +1259,7 @@ end
|
|
|
1258
1259
|
|
|
1259
1260
|
class ScenarioTest < Minitest::Test
|
|
1260
1261
|
def setup
|
|
1261
|
-
@fn =
|
|
1262
|
+
@fn = tempfile_path('extralite_scenario_test')
|
|
1262
1263
|
@db = Extralite::Database.new(@fn, legacy: true)
|
|
1263
1264
|
@db.query('create table if not exists t (x,y,z)')
|
|
1264
1265
|
@db.query('delete from t')
|
|
@@ -1411,7 +1412,7 @@ class BackupTest < Minitest::Test
|
|
|
1411
1412
|
end
|
|
1412
1413
|
|
|
1413
1414
|
def test_backup_with_fn
|
|
1414
|
-
tmp_fn =
|
|
1415
|
+
tmp_fn = tempfile_path('extralite_test_backup_with_fn')
|
|
1415
1416
|
@src.backup(tmp_fn)
|
|
1416
1417
|
|
|
1417
1418
|
db = Extralite::Database.new(tmp_fn)
|
|
@@ -1438,6 +1439,7 @@ class ConcurrencyTest < Minitest::Test
|
|
|
1438
1439
|
end
|
|
1439
1440
|
|
|
1440
1441
|
def test_gvl_always_release
|
|
1442
|
+
skip_with_gc_stress
|
|
1441
1443
|
skip if !IS_LINUX
|
|
1442
1444
|
|
|
1443
1445
|
delays = []
|
|
@@ -1522,6 +1524,7 @@ class ConcurrencyTest < Minitest::Test
|
|
|
1522
1524
|
end
|
|
1523
1525
|
|
|
1524
1526
|
def test_progress_handler_simple
|
|
1527
|
+
skip_with_gc_stress
|
|
1525
1528
|
db = Extralite::Database.new(':memory:')
|
|
1526
1529
|
|
|
1527
1530
|
# SQLite's behaviour post 3.46.0 has changed, such that the first time the
|
|
@@ -1714,6 +1717,7 @@ class ConcurrencyTest < Minitest::Test
|
|
|
1714
1717
|
SQL
|
|
1715
1718
|
|
|
1716
1719
|
def test_progress_handler_timeout_interrupt
|
|
1720
|
+
skip_with_gc_stress
|
|
1717
1721
|
db = Extralite::Database.new(':memory:')
|
|
1718
1722
|
t0 = Time.now
|
|
1719
1723
|
db.on_progress do
|
|
@@ -1756,6 +1760,7 @@ class ConcurrencyTest < Minitest::Test
|
|
|
1756
1760
|
end
|
|
1757
1761
|
|
|
1758
1762
|
def test_progress_handler_timeout_raise
|
|
1763
|
+
skip_with_gc_stress
|
|
1759
1764
|
db = Extralite::Database.new(':memory:')
|
|
1760
1765
|
t0 = Time.now
|
|
1761
1766
|
db.on_progress do
|
|
@@ -1795,7 +1800,8 @@ class ConcurrencyTest < Minitest::Test
|
|
|
1795
1800
|
end
|
|
1796
1801
|
|
|
1797
1802
|
def test_progress_handler_busy_timeout
|
|
1798
|
-
|
|
1803
|
+
skip_with_gc_stress
|
|
1804
|
+
fn = tempfile_path('extralite_test_progress_handler_busy_timeout')
|
|
1799
1805
|
db1 = Extralite::Database.new(fn)
|
|
1800
1806
|
db2 = Extralite::Database.new(fn)
|
|
1801
1807
|
|
|
@@ -1865,7 +1871,7 @@ class RactorTest < Minitest::Test
|
|
|
1865
1871
|
def test_ractor_simple
|
|
1866
1872
|
skip if SKIP_RACTOR_TESTS
|
|
1867
1873
|
|
|
1868
|
-
fn =
|
|
1874
|
+
fn = tempfile_path('extralite_test_database_in_ractor')
|
|
1869
1875
|
|
|
1870
1876
|
r = Ractor.new do
|
|
1871
1877
|
path = receive
|
|
@@ -1917,7 +1923,7 @@ class RactorTest < Minitest::Test
|
|
|
1917
1923
|
def test_ractor_stress
|
|
1918
1924
|
skip if SKIP_RACTOR_TESTS
|
|
1919
1925
|
|
|
1920
|
-
fn =
|
|
1926
|
+
fn = tempfile_path('extralite_test_ractor_stress')
|
|
1921
1927
|
random = Random.new.freeze
|
|
1922
1928
|
|
|
1923
1929
|
ractors = (0..9).map do |ractor_number|
|
|
@@ -2307,7 +2313,7 @@ class StmtCacheText < Minitest::Test
|
|
|
2307
2313
|
end
|
|
2308
2314
|
|
|
2309
2315
|
def test_stmt_cache_close
|
|
2310
|
-
fn =
|
|
2316
|
+
fn = tempfile_path('extralite_test_stmt_cache_close')
|
|
2311
2317
|
|
|
2312
2318
|
db = Extralite::Database.new(fn)
|
|
2313
2319
|
db.query('create table t (x)')
|
|
@@ -2324,7 +2330,7 @@ class StmtCacheText < Minitest::Test
|
|
|
2324
2330
|
end
|
|
2325
2331
|
|
|
2326
2332
|
def test_stmt_cache_gc
|
|
2327
|
-
fn =
|
|
2333
|
+
fn = tempfile_path('extralite_test_stmt_cache_gc')
|
|
2328
2334
|
|
|
2329
2335
|
db = Extralite::Database.new(fn)
|
|
2330
2336
|
db.query('create table t (x)')
|
|
@@ -2343,7 +2349,7 @@ class StmtCacheText < Minitest::Test
|
|
|
2343
2349
|
|
|
2344
2350
|
def test_stmt_cache_concurrent_access
|
|
2345
2351
|
# https://github.com/digital-fabric/extralite/issues/88
|
|
2346
|
-
fn =
|
|
2352
|
+
fn = tempfile_path('extralite_test_stmt_cache_concurrent_access')
|
|
2347
2353
|
|
|
2348
2354
|
a = Extralite::Database.new(fn)
|
|
2349
2355
|
a.execute("pragma journal_mode=wal")
|
|
@@ -2360,7 +2366,7 @@ class StmtCacheText < Minitest::Test
|
|
|
2360
2366
|
|
|
2361
2367
|
def test_stmt_cache_concurrent_transactions
|
|
2362
2368
|
# https://github.com/digital-fabric/extralite/issues/89
|
|
2363
|
-
fn =
|
|
2369
|
+
fn = tempfile_path('extralite_test_stmt_cache_concurrent_access')
|
|
2364
2370
|
|
|
2365
2371
|
a = Extralite::Database.new(fn)
|
|
2366
2372
|
a.execute('create table t (x)')
|
data/test/test_iterator.rb
CHANGED
|
@@ -118,7 +118,7 @@ class IteratorTest < Minitest::Test
|
|
|
118
118
|
end
|
|
119
119
|
|
|
120
120
|
def test_return_from_block_issue_26
|
|
121
|
-
fn =
|
|
121
|
+
fn = tempfile_path('extralite_test_return_from_block_issue_26')
|
|
122
122
|
db = Extralite::Database.new(fn)
|
|
123
123
|
|
|
124
124
|
λ = ->(sql) {
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: extralite
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.1.
|
|
4
|
+
version: 3.1.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sharon Rosner
|
|
@@ -88,6 +88,7 @@ extra_rdoc_files:
|
|
|
88
88
|
files:
|
|
89
89
|
- ".editorconfig"
|
|
90
90
|
- ".github/FUNDING.yml"
|
|
91
|
+
- ".github/workflows/test-asan.yml"
|
|
91
92
|
- ".github/workflows/test-bundle.yml"
|
|
92
93
|
- ".github/workflows/test.yml"
|
|
93
94
|
- ".gitignore"
|
|
@@ -174,7 +175,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
174
175
|
- !ruby/object:Gem::Version
|
|
175
176
|
version: '0'
|
|
176
177
|
requirements: []
|
|
177
|
-
rubygems_version: 4.0.
|
|
178
|
+
rubygems_version: 4.0.20
|
|
178
179
|
specification_version: 4
|
|
179
180
|
summary: Extra-lightweight SQLite3 wrapper for Ruby
|
|
180
181
|
test_files: []
|