pgtk 0.18.1 → 0.18.2
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/Gemfile +1 -1
- data/Gemfile.lock +32 -31
- data/lib/pgtk/stash.rb +5 -3
- data/lib/pgtk/version.rb +1 -1
- data/pgtk.gemspec +1 -1
- data/resources/pom.xml +2 -2
- metadata +2 -29
- data/.0pdd.yml +0 -12
- data/.gitattributes +0 -7
- data/.github/workflows/actionlint.yml +0 -25
- data/.github/workflows/codecov.yml +0 -31
- data/.github/workflows/copyrights.yml +0 -15
- data/.github/workflows/license.yml +0 -42
- data/.github/workflows/markdown-lint.yml +0 -23
- data/.github/workflows/pdd.yml +0 -19
- data/.github/workflows/rake.yml +0 -34
- data/.github/workflows/reuse.yml +0 -19
- data/.github/workflows/typos.yml +0 -19
- data/.github/workflows/xcop.yml +0 -21
- data/.github/workflows/yamllint.yml +0 -21
- data/.gitignore +0 -12
- data/.pdd +0 -7
- data/.rubocop.yml +0 -39
- data/.rultor.yml +0 -31
- data/.yamllint.yml +0 -7
- data/renovate.json +0 -6
- data/test/test__helper.rb +0 -76
- data/test/test_impatient.rb +0 -79
- data/test/test_liquibase_task.rb +0 -74
- data/test/test_pgsql_task.rb +0 -58
- data/test/test_pool.rb +0 -224
- data/test/test_retry.rb +0 -232
- data/test/test_stash.rb +0 -108
- data/test/test_wire.rb +0 -37
data/renovate.json
DELETED
data/test/test__helper.rb
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# SPDX-FileCopyrightText: Copyright (c) 2019-2025 Yegor Bugayenko
|
|
4
|
-
# SPDX-License-Identifier: MIT
|
|
5
|
-
|
|
6
|
-
$stdout.sync = true
|
|
7
|
-
|
|
8
|
-
require 'simplecov'
|
|
9
|
-
require 'simplecov-cobertura'
|
|
10
|
-
unless SimpleCov.running || ENV['PICKS']
|
|
11
|
-
SimpleCov.command_name('test')
|
|
12
|
-
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new(
|
|
13
|
-
[
|
|
14
|
-
SimpleCov::Formatter::HTMLFormatter,
|
|
15
|
-
SimpleCov::Formatter::CoberturaFormatter
|
|
16
|
-
]
|
|
17
|
-
)
|
|
18
|
-
SimpleCov.minimum_coverage 90
|
|
19
|
-
SimpleCov.minimum_coverage_by_file 90
|
|
20
|
-
SimpleCov.start do
|
|
21
|
-
add_filter 'test/'
|
|
22
|
-
add_filter 'vendor/'
|
|
23
|
-
add_filter 'target/'
|
|
24
|
-
track_files 'lib/**/*.rb'
|
|
25
|
-
track_files '*.rb'
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
require 'minitest/autorun'
|
|
30
|
-
require 'minitest/reporters'
|
|
31
|
-
Minitest::Reporters.use! [Minitest::Reporters::SpecReporter.new]
|
|
32
|
-
|
|
33
|
-
require 'logger'
|
|
34
|
-
require 'loog'
|
|
35
|
-
require 'rake'
|
|
36
|
-
require 'rake/tasklib'
|
|
37
|
-
require_relative '../lib/pgtk'
|
|
38
|
-
require_relative '../lib/pgtk/liquibase_task'
|
|
39
|
-
require_relative '../lib/pgtk/pgsql_task'
|
|
40
|
-
|
|
41
|
-
class Pgtk::Test < Minitest::Test
|
|
42
|
-
def fake_config
|
|
43
|
-
Dir.mktmpdir do |dir|
|
|
44
|
-
id = (Time.now.to_f * 1_000_000).to_i % 1_000_000
|
|
45
|
-
f = File.join(dir, 'cfg.yml')
|
|
46
|
-
Pgtk::PgsqlTask.new("pgsql#{id}") do |t|
|
|
47
|
-
t.dir = File.join(dir, 'pgsql')
|
|
48
|
-
t.user = 'hello'
|
|
49
|
-
t.password = 'A B C привет ! & | !'
|
|
50
|
-
t.dbname = 'test'
|
|
51
|
-
t.yaml = f
|
|
52
|
-
t.quiet = true
|
|
53
|
-
end
|
|
54
|
-
Rake::Task["pgsql#{id}"].invoke
|
|
55
|
-
Pgtk::LiquibaseTask.new("liquibase#{id}") do |t|
|
|
56
|
-
t.master = File.join(__dir__, '../test-resources/master.xml')
|
|
57
|
-
t.yaml = f
|
|
58
|
-
t.quiet = true
|
|
59
|
-
end
|
|
60
|
-
Rake::Task["liquibase#{id}"].invoke
|
|
61
|
-
assert_path_exists(f)
|
|
62
|
-
yield f
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def fake_pool(log: Loog::NULL)
|
|
67
|
-
fake_config do |f|
|
|
68
|
-
pool = Pgtk::Pool.new(
|
|
69
|
-
Pgtk::Wire::Yaml.new(f),
|
|
70
|
-
log: log
|
|
71
|
-
)
|
|
72
|
-
pool.start(1)
|
|
73
|
-
yield pool
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
end
|
data/test/test_impatient.rb
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# SPDX-FileCopyrightText: Copyright (c) 2019-2025 Yegor Bugayenko
|
|
4
|
-
# SPDX-License-Identifier: MIT
|
|
5
|
-
|
|
6
|
-
require 'loog'
|
|
7
|
-
require 'pg'
|
|
8
|
-
require 'qbash'
|
|
9
|
-
require 'rake'
|
|
10
|
-
require 'tmpdir'
|
|
11
|
-
require 'yaml'
|
|
12
|
-
require_relative 'test__helper'
|
|
13
|
-
require_relative '../lib/pgtk/pool'
|
|
14
|
-
require_relative '../lib/pgtk/impatient'
|
|
15
|
-
|
|
16
|
-
# Pool test.
|
|
17
|
-
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
18
|
-
# Copyright:: Copyright (c) 2017-2025 Yegor Bugayenko
|
|
19
|
-
# License:: MIT
|
|
20
|
-
class TestImpatient < Pgtk::Test
|
|
21
|
-
def test_takes_version
|
|
22
|
-
fake_pool do |pool|
|
|
23
|
-
v = Pgtk::Impatient.new(pool, 1).version
|
|
24
|
-
refute_nil(v)
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def test_interrupts
|
|
29
|
-
fake_pool do |pool|
|
|
30
|
-
assert_raises(Pgtk::Impatient::TooSlow) do
|
|
31
|
-
Pgtk::Impatient.new(pool, 0.01).exec(
|
|
32
|
-
'SELECT COUNT(*) FROM generate_series(1, 1000000) AS a'
|
|
33
|
-
)
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def test_skips_by_regex
|
|
39
|
-
fake_pool do |pool|
|
|
40
|
-
Pgtk::Impatient.new(pool, 0.01, /^SELECT.*$/).exec(
|
|
41
|
-
'SELECT COUNT(*) FROM generate_series(1, 1000000) AS a'
|
|
42
|
-
)
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def test_doesnt_shadow_larger_timeout
|
|
47
|
-
fake_pool do |pool|
|
|
48
|
-
assert_raises(Timeout::Error) do
|
|
49
|
-
Timeout.timeout(0.1) do
|
|
50
|
-
Pgtk::Impatient.new(pool, 999).exec(
|
|
51
|
-
'SELECT COUNT(*) FROM generate_series(1, 100000000) AS a'
|
|
52
|
-
)
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def test_doesnt_interrupt
|
|
59
|
-
fake_pool do |pool|
|
|
60
|
-
id = Pgtk::Impatient.new(pool, 1).exec(
|
|
61
|
-
'INSERT INTO book (title) VALUES ($1) RETURNING id',
|
|
62
|
-
['1984']
|
|
63
|
-
).first['id'].to_i
|
|
64
|
-
assert_predicate(id, :positive?)
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def test_doesnt_interrupt_in_transaction
|
|
69
|
-
fake_pool do |pool|
|
|
70
|
-
Pgtk::Impatient.new(pool, 1).transaction do |t|
|
|
71
|
-
id = t.exec(
|
|
72
|
-
'INSERT INTO book (title) VALUES ($1) RETURNING id',
|
|
73
|
-
['1984']
|
|
74
|
-
).first['id'].to_i
|
|
75
|
-
assert_predicate(id, :positive?)
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
end
|
data/test/test_liquibase_task.rb
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# SPDX-FileCopyrightText: Copyright (c) 2019-2025 Yegor Bugayenko
|
|
4
|
-
# SPDX-License-Identifier: MIT
|
|
5
|
-
|
|
6
|
-
require 'tmpdir'
|
|
7
|
-
require 'rake'
|
|
8
|
-
require 'yaml'
|
|
9
|
-
require_relative 'test__helper'
|
|
10
|
-
require_relative '../lib/pgtk/pgsql_task'
|
|
11
|
-
require_relative '../lib/pgtk/liquibase_task'
|
|
12
|
-
|
|
13
|
-
# Liquibase rake task test.
|
|
14
|
-
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
15
|
-
# Copyright:: Copyright (c) 2017-2025 Yegor Bugayenko
|
|
16
|
-
# License:: MIT
|
|
17
|
-
class TestLiquibaseTask < Pgtk::Test
|
|
18
|
-
def test_basic
|
|
19
|
-
Dir.mktmpdir do |dir|
|
|
20
|
-
Pgtk::PgsqlTask.new(:pgsql2) do |t|
|
|
21
|
-
t.dir = File.join(dir, 'pgsql')
|
|
22
|
-
t.user = 'hello'
|
|
23
|
-
t.password = 'A B C привет ! & | !'
|
|
24
|
-
t.dbname = 'test'
|
|
25
|
-
t.yaml = File.join(dir, 'cfg.yml')
|
|
26
|
-
t.quiet = true
|
|
27
|
-
end
|
|
28
|
-
Rake::Task['pgsql2'].invoke
|
|
29
|
-
Pgtk::LiquibaseTask.new(:liquibase2) do |t|
|
|
30
|
-
t.master = File.join(__dir__, '../test-resources/master.xml')
|
|
31
|
-
t.yaml = ['file-is-absent', File.join(dir, 'cfg.yml'), 'another']
|
|
32
|
-
t.quiet = true
|
|
33
|
-
t.postgresql_version = '42.7.0'
|
|
34
|
-
t.liquibase_version = '3.2.2'
|
|
35
|
-
t.contexts = '!test'
|
|
36
|
-
end
|
|
37
|
-
Rake::Task['liquibase2'].invoke
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def test_latest_version
|
|
42
|
-
Dir.mktmpdir do |dir|
|
|
43
|
-
Pgtk::PgsqlTask.new(:pgsql) do |t|
|
|
44
|
-
t.dir = File.join(dir, 'pgsql')
|
|
45
|
-
t.user = 'xxx'
|
|
46
|
-
t.password = 'xxx'
|
|
47
|
-
t.dbname = 'xxx'
|
|
48
|
-
t.yaml = File.join(dir, 'xxx.yml')
|
|
49
|
-
t.quiet = true
|
|
50
|
-
end
|
|
51
|
-
Rake::Task['pgsql'].invoke
|
|
52
|
-
Pgtk::LiquibaseTask.new(:liquibase) do |t|
|
|
53
|
-
t.master = File.join(__dir__, '../test-resources/master.xml')
|
|
54
|
-
t.yaml = File.join(dir, 'xxx.yml')
|
|
55
|
-
t.postgresql_version = '42.7.1'
|
|
56
|
-
t.liquibase_version = '4.25.1'
|
|
57
|
-
t.quiet = true
|
|
58
|
-
end
|
|
59
|
-
Rake::Task['liquibase'].invoke
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def test_with_invalid_master_file
|
|
64
|
-
Pgtk::LiquibaseTask.new(:lb) do |t|
|
|
65
|
-
t.master = 'the-file-doesnt-exist.xml'
|
|
66
|
-
t.yaml = { 'pgsql' => {} }
|
|
67
|
-
t.quiet = true
|
|
68
|
-
end
|
|
69
|
-
ex = assert_raises(StandardError) do
|
|
70
|
-
Rake::Task['lb'].invoke
|
|
71
|
-
end
|
|
72
|
-
assert_includes(ex.message, 'the-file-doesnt-exist.xml')
|
|
73
|
-
end
|
|
74
|
-
end
|
data/test/test_pgsql_task.rb
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# SPDX-FileCopyrightText: Copyright (c) 2019-2025 Yegor Bugayenko
|
|
4
|
-
# SPDX-License-Identifier: MIT
|
|
5
|
-
|
|
6
|
-
require 'rake'
|
|
7
|
-
require 'tmpdir'
|
|
8
|
-
require 'yaml'
|
|
9
|
-
require_relative 'test__helper'
|
|
10
|
-
require_relative '../lib/pgtk/pgsql_task'
|
|
11
|
-
|
|
12
|
-
# Pgsql rake task test.
|
|
13
|
-
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
14
|
-
# Copyright:: Copyright (c) 2017-2025 Yegor Bugayenko
|
|
15
|
-
# License:: MIT
|
|
16
|
-
class TestPgsqlTask < Pgtk::Test
|
|
17
|
-
def test_basic
|
|
18
|
-
Dir.mktmpdir do |dir|
|
|
19
|
-
Pgtk::PgsqlTask.new(:p2) do |t|
|
|
20
|
-
t.dir = File.join(dir, 'pgsql')
|
|
21
|
-
t.user = 'hello'
|
|
22
|
-
t.password = 'A B C привет ! & | !'
|
|
23
|
-
t.dbname = 'test'
|
|
24
|
-
t.yaml = File.join(dir, 'cfg.yml')
|
|
25
|
-
t.quiet = true
|
|
26
|
-
t.config = {
|
|
27
|
-
log_min_error_statement: 'ERROR'
|
|
28
|
-
}
|
|
29
|
-
end
|
|
30
|
-
Rake::Task['p2'].invoke
|
|
31
|
-
yaml = YAML.load_file(File.join(dir, 'cfg.yml'))
|
|
32
|
-
assert(yaml['pgsql']['url'].start_with?('jdbc:postgresql://localhost'))
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def test_not_quiet
|
|
37
|
-
Dir.mktmpdir do |dir|
|
|
38
|
-
Pgtk::PgsqlTask.new(:p3) do |t|
|
|
39
|
-
t.dir = File.join(dir, 'pgsql')
|
|
40
|
-
t.user = 'hello'
|
|
41
|
-
t.password = 'the password'
|
|
42
|
-
t.dbname = 'test'
|
|
43
|
-
t.yaml = File.join(dir, 'cfg.yml')
|
|
44
|
-
t.quiet = true
|
|
45
|
-
t.config = {
|
|
46
|
-
log_directory: dir,
|
|
47
|
-
logging_collector: 'on',
|
|
48
|
-
log_statement: 'all',
|
|
49
|
-
log_filename: 'pgsql.log'
|
|
50
|
-
}
|
|
51
|
-
end
|
|
52
|
-
Rake::Task['p3'].invoke
|
|
53
|
-
yaml = YAML.load_file(File.join(dir, 'cfg.yml'))
|
|
54
|
-
assert(yaml['pgsql']['url'].start_with?('jdbc:postgresql://localhost'))
|
|
55
|
-
assert_path_exists(File.join(dir, 'pgsql.log'))
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
end
|
data/test/test_pool.rb
DELETED
|
@@ -1,224 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# SPDX-FileCopyrightText: Copyright (c) 2019-2025 Yegor Bugayenko
|
|
4
|
-
# SPDX-License-Identifier: MIT
|
|
5
|
-
|
|
6
|
-
require 'loog'
|
|
7
|
-
require 'pg'
|
|
8
|
-
require 'qbash'
|
|
9
|
-
require 'rake'
|
|
10
|
-
require 'tmpdir'
|
|
11
|
-
require 'yaml'
|
|
12
|
-
require_relative 'test__helper'
|
|
13
|
-
require_relative '../lib/pgtk/liquibase_task'
|
|
14
|
-
require_relative '../lib/pgtk/pgsql_task'
|
|
15
|
-
require_relative '../lib/pgtk/pool'
|
|
16
|
-
require_relative '../lib/pgtk/spy'
|
|
17
|
-
|
|
18
|
-
# Pool test.
|
|
19
|
-
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
20
|
-
# Copyright:: Copyright (c) 2017-2025 Yegor Bugayenko
|
|
21
|
-
# License:: MIT
|
|
22
|
-
class TestPool < Pgtk::Test
|
|
23
|
-
def test_reads_version
|
|
24
|
-
fake_pool do |pool|
|
|
25
|
-
ver = pool.version
|
|
26
|
-
assert(ver.start_with?('1'))
|
|
27
|
-
refute_includes(ver, ' ')
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def test_basic
|
|
32
|
-
fake_pool do |pool|
|
|
33
|
-
id = pool.exec(
|
|
34
|
-
'INSERT INTO book (title) VALUES ($1) RETURNING id',
|
|
35
|
-
['Elegant Objects']
|
|
36
|
-
)[0]['id'].to_i
|
|
37
|
-
assert_predicate(id, :positive?)
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def test_logs_pgsql_errors_to_logger
|
|
42
|
-
buf = Loog::Buffer.new
|
|
43
|
-
fake_pool(log: buf) do |pool|
|
|
44
|
-
pool.exec(
|
|
45
|
-
"
|
|
46
|
-
CREATE FUNCTION intentional_failure() RETURNS trigger AS
|
|
47
|
-
'BEGIN
|
|
48
|
-
IF NEW.title = ''War and War'' THEN
|
|
49
|
-
RAISE EXCEPTION ''The title of the book is bad'';
|
|
50
|
-
END IF;
|
|
51
|
-
RETURN NEW;
|
|
52
|
-
END' LANGUAGE PLPGSQL
|
|
53
|
-
"
|
|
54
|
-
)
|
|
55
|
-
pool.exec(
|
|
56
|
-
"
|
|
57
|
-
CREATE TRIGGER check_book_title
|
|
58
|
-
BEFORE INSERT ON book
|
|
59
|
-
FOR EACH ROW EXECUTE PROCEDURE intentional_failure();
|
|
60
|
-
"
|
|
61
|
-
)
|
|
62
|
-
assert_raises(PG::RaiseException) do
|
|
63
|
-
pool.exec('INSERT INTO book (title) VALUES ($1)', ['War and War'])
|
|
64
|
-
end
|
|
65
|
-
assert_includes(buf.to_s, 'The title of the book is bad')
|
|
66
|
-
assert_includes(buf.to_s, 'function intentional_failure() line 3')
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
def test_queries_with_block
|
|
71
|
-
fake_pool do |pool|
|
|
72
|
-
pool.exec('INSERT INTO book (title) VALUES ($1)', ['1984'])
|
|
73
|
-
rows = []
|
|
74
|
-
pool.exec('SELECT * FROM book') do |row|
|
|
75
|
-
rows.append(row)
|
|
76
|
-
end
|
|
77
|
-
assert_equal(1, rows.size)
|
|
78
|
-
end
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
def test_with_spy
|
|
82
|
-
queries = []
|
|
83
|
-
fake_pool do |pool|
|
|
84
|
-
pool = Pgtk::Spy.new(pool) { |sql| queries.append(sql) }
|
|
85
|
-
pool.exec(
|
|
86
|
-
['INSERT INTO book', '(title) VALUES ($1)'],
|
|
87
|
-
['Elegant Objects']
|
|
88
|
-
)
|
|
89
|
-
end
|
|
90
|
-
assert_equal(1, queries.size)
|
|
91
|
-
assert_equal('INSERT INTO book (title) VALUES ($1)', queries.first)
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
def test_complex_query
|
|
95
|
-
fake_pool do |pool|
|
|
96
|
-
pool.exec(
|
|
97
|
-
"
|
|
98
|
-
INSERT INTO book (title) VALUES ('one');
|
|
99
|
-
INSERT INTO book (title) VALUES ('two');
|
|
100
|
-
"
|
|
101
|
-
)
|
|
102
|
-
end
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
def test_logs_sql
|
|
106
|
-
log = Loog::Buffer.new
|
|
107
|
-
fake_pool(log: log) do |pool|
|
|
108
|
-
pool.exec(
|
|
109
|
-
'INSERT INTO book (title) VALUES ($1)',
|
|
110
|
-
['Object Thinking']
|
|
111
|
-
)
|
|
112
|
-
assert_includes(log.to_s, 'INSERT INTO book (title) VALUES ($1)')
|
|
113
|
-
end
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
def test_logs_errors
|
|
117
|
-
log = Loog::Buffer.new
|
|
118
|
-
fake_pool(log: log) do |pool|
|
|
119
|
-
assert_raises(PG::UndefinedTable) do
|
|
120
|
-
pool.exec('INSERT INTO tableDoesNotExist (a) VALUES (42)')
|
|
121
|
-
end
|
|
122
|
-
assert_includes(log.to_s, 'INSERT INTO tableDoesNotExist')
|
|
123
|
-
end
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
def test_transaction
|
|
127
|
-
fake_pool do |pool|
|
|
128
|
-
id = Pgtk::Spy.new(pool).transaction do |t|
|
|
129
|
-
t.exec('DELETE FROM book')
|
|
130
|
-
t.exec(
|
|
131
|
-
[
|
|
132
|
-
'INSERT INTO book (title)',
|
|
133
|
-
'VALUES ($1) RETURNING id'
|
|
134
|
-
],
|
|
135
|
-
['Object Thinking']
|
|
136
|
-
)[0]['id'].to_i
|
|
137
|
-
end
|
|
138
|
-
assert_predicate(id, :positive?)
|
|
139
|
-
end
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
def test_transaction_with_error
|
|
143
|
-
fake_pool do |pool|
|
|
144
|
-
pool.exec('DELETE FROM book')
|
|
145
|
-
assert_empty(pool.exec('SELECT * FROM book'))
|
|
146
|
-
assert_raises(StandardError) do
|
|
147
|
-
pool.transaction do |t|
|
|
148
|
-
t.exec('INSERT INTO book (title) VALUES ($1)', ['hey'])
|
|
149
|
-
t.exec('INSERT INTO book (error_here) VALUES ($1)', ['hey'])
|
|
150
|
-
end
|
|
151
|
-
end
|
|
152
|
-
assert_empty(pool.exec('SELECT * FROM book'))
|
|
153
|
-
pool.exec('INSERT INTO book (title) VALUES ($1)', ['another'])
|
|
154
|
-
refute_empty(pool.exec('SELECT * FROM book'))
|
|
155
|
-
end
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
def test_reconnects_on_pg_error
|
|
159
|
-
fake_pool do |pool|
|
|
160
|
-
assert_raises PG::UndefinedTable do
|
|
161
|
-
pool.exec('SELECT * FROM thisiserror')
|
|
162
|
-
end
|
|
163
|
-
5.times do
|
|
164
|
-
pool.exec('SELECT * FROM book')
|
|
165
|
-
end
|
|
166
|
-
end
|
|
167
|
-
end
|
|
168
|
-
|
|
169
|
-
def test_reconnects_on_pg_reboot
|
|
170
|
-
port = RandomPort::Pool::SINGLETON.acquire
|
|
171
|
-
Dir.mktmpdir do |dir|
|
|
172
|
-
id = rand(100..999)
|
|
173
|
-
Pgtk::PgsqlTask.new("pgsql#{id}") do |t|
|
|
174
|
-
t.dir = File.join(dir, 'pgsql')
|
|
175
|
-
t.user = 'hello'
|
|
176
|
-
t.password = 'A B C привет ! & | !'
|
|
177
|
-
t.dbname = 'test'
|
|
178
|
-
t.yaml = File.join(dir, 'cfg.yml')
|
|
179
|
-
t.quiet = true
|
|
180
|
-
t.fresh_start = true
|
|
181
|
-
t.port = port
|
|
182
|
-
end
|
|
183
|
-
task = Rake::Task["pgsql#{id}"]
|
|
184
|
-
task.invoke
|
|
185
|
-
pool = Pgtk::Pool.new(
|
|
186
|
-
Pgtk::Wire::Yaml.new(File.join(dir, 'cfg.yml')),
|
|
187
|
-
log: Loog::NULL
|
|
188
|
-
)
|
|
189
|
-
pool.start(1)
|
|
190
|
-
pool.exec('SELECT * FROM pg_catalog.pg_tables')
|
|
191
|
-
qbash("pg_ctl -D #{Shellwords.escape(File.join(dir, 'pgsql'))} stop", log: nil)
|
|
192
|
-
cycle = 0
|
|
193
|
-
loop do
|
|
194
|
-
begin
|
|
195
|
-
TCPSocket.new('localhost', port)
|
|
196
|
-
sleep(0.1)
|
|
197
|
-
cycle += 1
|
|
198
|
-
if cycle > 50
|
|
199
|
-
qbash('ps -ax | grep postgres')
|
|
200
|
-
raise "Can't stop running postgres at port #{port}, for some reason"
|
|
201
|
-
end
|
|
202
|
-
rescue StandardError => e
|
|
203
|
-
puts e.message
|
|
204
|
-
break
|
|
205
|
-
end
|
|
206
|
-
end
|
|
207
|
-
assert_raises(PG::UnableToSend, PG::ConnectionBad) do
|
|
208
|
-
pool.exec('SELECT * FROM pg_catalog.pg_tables')
|
|
209
|
-
end
|
|
210
|
-
task.reenable
|
|
211
|
-
task.invoke
|
|
212
|
-
loop do
|
|
213
|
-
begin
|
|
214
|
-
pool.exec('SELECT * FROM pg_catalog.pg_tables')
|
|
215
|
-
break
|
|
216
|
-
rescue StandardError => e
|
|
217
|
-
puts e.message
|
|
218
|
-
sleep(0.1)
|
|
219
|
-
retry
|
|
220
|
-
end
|
|
221
|
-
end
|
|
222
|
-
end
|
|
223
|
-
end
|
|
224
|
-
end
|