tiny_tds 2.1.2 → 3.2.1
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 +5 -5
- data/.github/workflows/ci.yml +571 -0
- data/.gitignore +2 -0
- data/CHANGELOG.md +56 -1
- data/Gemfile +1 -8
- data/ISSUE_TEMPLATE.md +1 -1
- data/README.md +89 -89
- data/Rakefile +44 -30
- data/VERSION +1 -1
- data/docker-compose.yml +34 -0
- data/ext/tiny_tds/client.c +100 -59
- data/ext/tiny_tds/client.h +5 -3
- data/ext/tiny_tds/extconf.rb +173 -52
- data/ext/tiny_tds/extconsts.rb +4 -11
- data/ext/tiny_tds/result.c +52 -45
- data/ext/tiny_tds/tiny_tds_ext.c +4 -1
- data/lib/tiny_tds/bin.rb +12 -26
- data/lib/tiny_tds/client.rb +38 -42
- data/lib/tiny_tds/error.rb +0 -2
- data/lib/tiny_tds/gem.rb +5 -14
- data/lib/tiny_tds/result.rb +0 -2
- data/lib/tiny_tds/version.rb +1 -1
- data/lib/tiny_tds.rb +28 -47
- data/setup_cimgruby_dev.sh +25 -0
- data/start_dev.sh +21 -0
- data/tasks/native_gem.rake +12 -10
- data/tasks/package.rake +1 -3
- data/tasks/ports.rake +14 -77
- data/tasks/test.rake +3 -5
- data/test/bin/install-freetds.sh +2 -4
- data/test/bin/install-mssql.ps1 +42 -0
- data/test/bin/install-mssqltools.sh +9 -0
- data/test/bin/restore-from-native-gem.ps1 +10 -0
- data/test/bin/setup_tinytds_db.sh +7 -0
- data/test/bin/setup_volume_permissions.sh +10 -0
- data/test/client_test.rb +152 -116
- data/test/gem_test.rb +39 -118
- data/test/result_test.rb +285 -350
- data/test/schema_test.rb +369 -395
- data/test/sql/db-create.sql +18 -0
- data/test/sql/db-login.sql +38 -0
- data/test/test_helper.rb +112 -85
- data/test/thread_test.rb +22 -31
- data/tiny_tds.gemspec +28 -26
- metadata +85 -59
- data/.travis.yml +0 -24
- data/BACKERS.md +0 -32
- data/appveyor.yml +0 -51
- data/tasks/ports/freetds.rb +0 -37
- data/tasks/ports/libiconv.rb +0 -43
- data/tasks/ports/openssl.rb +0 -78
- data/tasks/ports/recipe.rb +0 -52
- data/test/appveyor/dbsetup.ps1 +0 -27
- data/test/appveyor/dbsetup.sql +0 -9
- data/test/benchmark/query.rb +0 -77
- data/test/benchmark/query_odbc.rb +0 -106
- data/test/benchmark/query_tinytds.rb +0 -126
- data/test/bin/setup.sh +0 -19
- data/test/schema/sqlserver_2000.sql +0 -140
- data/test/schema/sqlserver_2005.sql +0 -140
- data/test/schema/sqlserver_2014.sql +0 -140
- data/test/schema/sqlserver_2016.sql +0 -140
- data/test/schema/sybase_ase.sql +0 -138
- /data/test/schema/{sqlserver_2008.sql → sqlserver_2017.sql} +0 -0
data/tasks/ports.rake
CHANGED
@@ -1,87 +1,24 @@
|
|
1
|
-
|
2
|
-
require 'mini_portile2'
|
3
|
-
require 'fileutils'
|
4
|
-
require_relative 'ports/libiconv'
|
5
|
-
require_relative 'ports/openssl'
|
6
|
-
require_relative 'ports/freetds'
|
7
|
-
require_relative '../ext/tiny_tds/extconsts'
|
8
|
-
|
9
|
-
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE if defined? OpenSSL
|
1
|
+
require_relative "../ext/tiny_tds/extconsts"
|
10
2
|
|
11
3
|
namespace :ports do
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
task :openssl, [:host] do |task, args|
|
19
|
-
args.with_defaults(host: RbConfig::CONFIG['host'])
|
4
|
+
libraries_to_compile = {
|
5
|
+
openssl: OPENSSL_VERSION,
|
6
|
+
libiconv: ICONV_VERSION,
|
7
|
+
freetds: FREETDS_VERSION
|
8
|
+
}
|
20
9
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
openssl.activate
|
25
|
-
end
|
26
|
-
|
27
|
-
task :libiconv, [:host] do |task, args|
|
28
|
-
args.with_defaults(host: RbConfig::CONFIG['host'])
|
10
|
+
desc "Notes the actual versions for the compiled ports into a file"
|
11
|
+
task "version_file", [:gem_platform] do |_task, args|
|
12
|
+
args.with_defaults(gem_platform: RbConfig::CONFIG["arch"])
|
29
13
|
|
30
|
-
|
31
|
-
libiconv.host = args.host
|
32
|
-
libiconv.cook
|
33
|
-
libiconv.activate
|
34
|
-
end
|
14
|
+
ports_version = {}
|
35
15
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
freetds.files = [FREETDS_SOURCE_URI]
|
40
|
-
freetds.host = args.host
|
41
|
-
|
42
|
-
if openssl
|
43
|
-
# freetds doesn't have an option that will provide an rpath
|
44
|
-
# so we do it manually
|
45
|
-
ENV['OPENSSL_CFLAGS'] = "-Wl,-rpath -Wl,#{openssl.path}/lib"
|
46
|
-
# Add the pkgconfig file with MSYS2'ish path, to prefer our ports build
|
47
|
-
# over MSYS2 system OpenSSL.
|
48
|
-
ENV['PKG_CONFIG_PATH'] = "#{openssl.path.gsub(/^(\w):/i){"/"+$1.downcase}}/lib/pkgconfig:#{ENV['PKG_CONFIG_PATH']}"
|
49
|
-
freetds.configure_options << "--with-openssl=#{openssl.path}"
|
16
|
+
libraries_to_compile.each do |library, version|
|
17
|
+
ports_version[library] = version
|
50
18
|
end
|
51
19
|
|
52
|
-
|
53
|
-
freetds.configure_options << "--with-libiconv-prefix=#{libiconv.path}"
|
54
|
-
end
|
20
|
+
ports_version[:platform] = args.gem_platform
|
55
21
|
|
56
|
-
|
57
|
-
freetds.activate
|
58
|
-
end
|
59
|
-
|
60
|
-
task :compile, [:host] do |task,args|
|
61
|
-
args.with_defaults(host: RbConfig::CONFIG['host'])
|
62
|
-
|
63
|
-
puts "Compiling ports for #{args.host}..."
|
64
|
-
|
65
|
-
['openssl','libiconv','freetds'].each do |lib|
|
66
|
-
Rake::Task["ports:#{lib}"].invoke(args.host)
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
desc 'Build the ports windows binaries via rake-compiler-dock'
|
71
|
-
task 'cross' do
|
72
|
-
require 'rake_compiler_dock'
|
73
|
-
|
74
|
-
# make sure to install our bundle
|
75
|
-
build = ['bundle']
|
76
|
-
|
77
|
-
# build the ports for all our cross compile hosts
|
78
|
-
GEM_PLATFORM_HOSTS.each do |gem_platform, host|
|
79
|
-
build << "rake ports:compile[#{host}] MAKE='make -j`nproc`'"
|
80
|
-
end
|
81
|
-
|
82
|
-
RakeCompilerDock.sh build.join(' && ')
|
22
|
+
File.write(".ports_versions", ports_version)
|
83
23
|
end
|
84
24
|
end
|
85
|
-
|
86
|
-
desc 'Build ports and activate libraries for the current architecture.'
|
87
|
-
task :ports => ['ports:compile']
|
data/tasks/test.rake
CHANGED
@@ -1,9 +1,7 @@
|
|
1
|
-
|
2
|
-
require 'rake/testtask'
|
1
|
+
require "rake/testtask"
|
3
2
|
|
4
3
|
Rake::TestTask.new do |t|
|
5
|
-
t.libs <<
|
6
|
-
t.test_files = FileList[
|
4
|
+
t.libs << "test"
|
5
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
7
6
|
t.verbose = true
|
8
7
|
end
|
9
|
-
|
data/test/bin/install-freetds.sh
CHANGED
@@ -10,11 +10,9 @@ fi
|
|
10
10
|
wget http://www.freetds.org/files/stable/freetds-$FREETDS_VERSION.tar.gz
|
11
11
|
tar -xzf freetds-$FREETDS_VERSION.tar.gz
|
12
12
|
cd freetds-$FREETDS_VERSION
|
13
|
-
./configure
|
14
|
-
--with-openssl=/opt/local \
|
15
|
-
--with-tdsver=7.3
|
13
|
+
./configure
|
16
14
|
make
|
17
|
-
make install
|
15
|
+
sudo make install
|
18
16
|
cd ..
|
19
17
|
rm -rf freetds-$FREETDS_VERSION
|
20
18
|
rm freetds-$FREETDS_VERSION.tar.gz
|
@@ -0,0 +1,42 @@
|
|
1
|
+
param ([int] $Version)
|
2
|
+
|
3
|
+
$ProgressPreference = 'SilentlyContinue'
|
4
|
+
|
5
|
+
$DownloadLinkTable = @{
|
6
|
+
2017 = "https://go.microsoft.com/fwlink/?linkid=829176";
|
7
|
+
2019 = "https://download.microsoft.com/download/7/c/1/7c14e92e-bdcb-4f89-b7cf-93543e7112d1/SQLEXPR_x64_ENU.exe";
|
8
|
+
2022 = "https://download.microsoft.com/download/3/8/d/38de7036-2433-4207-8eae-06e247e17b25/SQLEXPR_x64_ENU.exe";
|
9
|
+
}
|
10
|
+
|
11
|
+
$MajorVersionTable = @{
|
12
|
+
2017 = 14;
|
13
|
+
2019 = 15;
|
14
|
+
2022 = 16;
|
15
|
+
}
|
16
|
+
|
17
|
+
if (-not(Test-path "C:\Downloads")) {
|
18
|
+
mkdir "C:\Downloads"
|
19
|
+
}
|
20
|
+
|
21
|
+
$sqlInstallationFile = "C:\Downloads\sqlexpress.exe"
|
22
|
+
if (-not(Test-path $sqlInstallationFile -PathType leaf)) {
|
23
|
+
Write-Host "Downloading SQL Express ..."
|
24
|
+
Invoke-WebRequest -Uri $DownloadLinkTable[$Version] -OutFile "C:\Downloads\sqlexpress.exe"
|
25
|
+
}
|
26
|
+
|
27
|
+
Write-Host "Installing SQL Express ..."
|
28
|
+
Start-Process -Wait -FilePath "C:\Downloads\sqlexpress.exe" -ArgumentList /qs, /x:"C:\Downloads\setup"
|
29
|
+
C:\Downloads\setup\setup.exe /q /ACTION=Install /INSTANCENAME=SQLEXPRESS /FEATURES=SQLEngine /UPDATEENABLED=0 /SQLSVCACCOUNT='NT AUTHORITY\System' /SQLSYSADMINACCOUNTS='BUILTIN\ADMINISTRATORS' /TCPENABLED=1 /NPENABLED=0 /IACCEPTSQLSERVERLICENSETERMS
|
30
|
+
|
31
|
+
Write-Host "Configuring SQL Express ..."
|
32
|
+
stop-service MSSQL`$SQLEXPRESS
|
33
|
+
set-itemproperty -path "HKLM:\software\microsoft\microsoft sql server\mssql$($MajorVersionTable[$Version]).SQLEXPRESS\mssqlserver\supersocketnetlib\tcp\ipall" -name tcpdynamicports -value ''
|
34
|
+
set-itemproperty -path "HKLM:\software\microsoft\microsoft sql server\mssql$($MajorVersionTable[$Version]).SQLEXPRESS\mssqlserver\supersocketnetlib\tcp\ipall" -name tcpport -value 1433
|
35
|
+
set-itemproperty -path "HKLM:\software\microsoft\microsoft sql server\mssql$($MajorVersionTable[$Version]).SQLEXPRESS\mssqlserver\" -name LoginMode -value 2
|
36
|
+
|
37
|
+
Write-Host "Starting SQL Express ..."
|
38
|
+
start-service MSSQL`$SQLEXPRESS
|
39
|
+
|
40
|
+
Write-Host "Configuring MSSQL for TinyTDS ..."
|
41
|
+
& sqlcmd -i './test/sql/db-create.sql'
|
42
|
+
& sqlcmd -i './test/sql/db-login.sql'
|
@@ -0,0 +1,9 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
set -x
|
4
|
+
set -e
|
5
|
+
|
6
|
+
curl https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add -
|
7
|
+
curl https://packages.microsoft.com/config/ubuntu/20.04/prod.list | sudo tee /etc/apt/sources.list.d/msprod.list
|
8
|
+
sudo apt-get update
|
9
|
+
sudo ACCEPT_EULA=Y apt-get -y install mssql-tools unixodbc-dev
|
@@ -0,0 +1,10 @@
|
|
1
|
+
$gemVersion = (Get-Content VERSION).Trim()
|
2
|
+
$gemToUnpack = "./tiny_tds-$gemVersion-$env:RUBY_ARCHITECTURE.gem"
|
3
|
+
|
4
|
+
Write-Host "Looking to unpack $gemToUnpack"
|
5
|
+
gem unpack --target ./tmp "$gemToUnpack"
|
6
|
+
|
7
|
+
# Restore precompiled code
|
8
|
+
$source = (Resolve-Path ".\tmp\tiny_tds-$gemVersion-$env:RUBY_ARCHITECTURE\lib\tiny_tds").Path
|
9
|
+
$destination = (Resolve-Path ".\lib\tiny_tds").Path
|
10
|
+
Get-ChildItem $source -Recurse -Exclude "*.rb" | Copy-Item -Destination {Join-Path $destination $_.FullName.Substring($source.length)}
|
@@ -0,0 +1,10 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
set -x
|
4
|
+
|
5
|
+
sudo groupadd -g 3434 circleci_tinytds
|
6
|
+
sudo usermod -a -G circleci_tinytds $USER
|
7
|
+
sudo useradd circleci_tinytds -u 3434 -g 3434
|
8
|
+
sudo usermod -a -G circleci_tinytds circleci_tinytds
|
9
|
+
sudo chgrp -R circleci_tinytds .
|
10
|
+
sudo chmod -R g+rwx .
|
data/test/client_test.rb
CHANGED
@@ -1,126 +1,123 @@
|
|
1
|
-
|
2
|
-
require 'test_helper'
|
1
|
+
require "test_helper"
|
3
2
|
|
4
3
|
class ClientTest < TinyTds::TestCase
|
5
|
-
|
6
|
-
describe 'With valid credentials' do
|
7
|
-
|
4
|
+
describe "with valid credentials" do
|
8
5
|
before do
|
9
6
|
@client = new_connection
|
10
7
|
end
|
11
8
|
|
12
|
-
it
|
9
|
+
it "must not be closed" do
|
13
10
|
assert !@client.closed?
|
14
11
|
assert @client.active?
|
15
12
|
end
|
16
13
|
|
17
|
-
it
|
14
|
+
it "allows client connection to be closed" do
|
18
15
|
assert @client.close
|
19
16
|
assert @client.closed?
|
20
17
|
assert !@client.active?
|
21
|
-
|
18
|
+
assert @client.dead?
|
19
|
+
action = lambda { @client.execute("SELECT 1 as [one]").each }
|
22
20
|
assert_raise_tinytds_error(action) do |e|
|
23
|
-
assert_match %r{closed connection}i, e.message,
|
21
|
+
assert_match %r{closed connection}i, e.message, "ignore if non-english test run"
|
24
22
|
end
|
25
23
|
end
|
26
24
|
|
27
|
-
it
|
28
|
-
if
|
29
|
-
assert_equal 7, @client.tds_version
|
30
|
-
assert_equal 'DBTDS_5_0 - 5.0 SQL Server', @client.tds_version_info
|
31
|
-
elsif @client.tds_73?
|
25
|
+
it "has getters for the tds version information (brittle since conf takes precedence)" do
|
26
|
+
if @client.tds_73?
|
32
27
|
assert_equal 11, @client.tds_version
|
33
|
-
assert_equal
|
28
|
+
assert_equal "DBTDS_7_3 - Microsoft SQL Server 2008", @client.tds_version_info
|
34
29
|
else
|
35
30
|
assert_equal 9, @client.tds_version
|
36
|
-
assert_equal
|
31
|
+
assert_equal "DBTDS_7_1/DBTDS_8_0 - Microsoft SQL Server 2000", @client.tds_version_info
|
37
32
|
end
|
38
33
|
end
|
39
34
|
|
40
|
-
it
|
41
|
-
assert_equal
|
42
|
-
assert_equal Encoding.find(
|
35
|
+
it "uses UTF-8 client charset/encoding by default" do
|
36
|
+
assert_equal "UTF-8", @client.charset
|
37
|
+
assert_equal Encoding.find("UTF-8"), @client.encoding
|
43
38
|
end
|
44
39
|
|
45
|
-
it
|
40
|
+
it "has a #escape method used for quote strings" do
|
46
41
|
assert_equal "''hello''", @client.escape("'hello'")
|
47
42
|
end
|
48
43
|
|
49
|
-
[
|
44
|
+
["CP850", "CP1252", "ISO-8859-1"].each do |encoding|
|
50
45
|
it "allows valid iconv character set - #{encoding}" do
|
46
|
+
client = new_connection(encoding: encoding)
|
47
|
+
assert_equal encoding, client.charset
|
48
|
+
assert_equal Encoding.find(encoding), client.encoding
|
49
|
+
ensure
|
50
|
+
client&.close
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
unless sqlserver_azure?
|
55
|
+
it "must be able to use :host/:port connection" do
|
56
|
+
host = ENV["TINYTDS_UNIT_HOST_TEST"] || ENV["TINYTDS_UNIT_HOST"] || "localhost"
|
57
|
+
port = ENV["TINYTDS_UNIT_PORT_TEST"] || ENV["TINYTDS_UNIT_PORT"] || 1433
|
51
58
|
begin
|
52
|
-
client = new_connection
|
53
|
-
assert_equal encoding, client.charset
|
54
|
-
assert_equal Encoding.find(encoding), client.encoding
|
59
|
+
client = new_connection dataserver: nil, host: host, port: port
|
55
60
|
ensure
|
56
|
-
client
|
61
|
+
client&.close
|
57
62
|
end
|
58
63
|
end
|
59
64
|
end
|
60
|
-
|
61
|
-
it 'must be able to use :host/:port connection' do
|
62
|
-
host = ENV['TINYTDS_UNIT_HOST_TEST'] || ENV['TINYTDS_UNIT_HOST'] || 'localhost'
|
63
|
-
port = ENV['TINYTDS_UNIT_PORT_TEST'] || ENV['TINYTDS_UNIT_PORT'] || 1433
|
64
|
-
begin
|
65
|
-
client = new_connection dataserver: nil, host: host, port: port
|
66
|
-
ensure
|
67
|
-
client.close if client
|
68
|
-
end
|
69
|
-
end unless sqlserver_azure?
|
70
|
-
|
71
65
|
end
|
72
66
|
|
73
|
-
describe
|
67
|
+
describe "With in-valid options" do
|
68
|
+
before(:all) do
|
69
|
+
init_toxiproxy
|
70
|
+
end
|
74
71
|
|
75
|
-
it
|
76
|
-
assert_raises(ArgumentError) { new_connection :
|
72
|
+
it "raises an argument error when no :host given and :dataserver is blank" do
|
73
|
+
assert_raises(ArgumentError) { new_connection dataserver: nil, host: nil }
|
77
74
|
end
|
78
75
|
|
79
|
-
it
|
80
|
-
assert_raises(ArgumentError) { TinyTds::Client.new :
|
76
|
+
it "raises an argument error when no :username is supplied" do
|
77
|
+
assert_raises(ArgumentError) { TinyTds::Client.new username: nil }
|
81
78
|
end
|
82
79
|
|
83
|
-
it
|
84
|
-
options = connection_options :
|
80
|
+
it "raises TinyTds exception with undefined :dataserver" do
|
81
|
+
options = connection_options login_timeout: 1, dataserver: "DOESNOTEXIST"
|
85
82
|
action = lambda { new_connection(options) }
|
86
83
|
assert_raise_tinytds_error(action) do |e|
|
87
84
|
# Not sure why tese are different.
|
88
85
|
if ruby_darwin?
|
89
86
|
assert_equal 20009, e.db_error_number
|
90
87
|
assert_equal 9, e.severity
|
91
|
-
assert_match %r{is unavailable or does not exist}i, e.message,
|
88
|
+
assert_match %r{is unavailable or does not exist}i, e.message, "ignore if non-english test run"
|
92
89
|
else
|
93
90
|
assert_equal 20012, e.db_error_number
|
94
91
|
assert_equal 2, e.severity
|
95
|
-
assert_match %r{server name not found in configuration files}i, e.message,
|
92
|
+
assert_match %r{server name not found in configuration files}i, e.message, "ignore if non-english test run"
|
96
93
|
end
|
97
94
|
end
|
98
95
|
assert_new_connections_work
|
99
96
|
end
|
100
97
|
|
101
|
-
it
|
102
|
-
client = new_connection :
|
98
|
+
it "raises TinyTds exception with long query past :timeout option" do
|
99
|
+
client = new_connection timeout: 1
|
103
100
|
action = lambda { client.execute("WaitFor Delay '00:00:02'").do }
|
104
101
|
assert_raise_tinytds_error(action) do |e|
|
105
102
|
assert_equal 20003, e.db_error_number
|
106
103
|
assert_equal 6, e.severity
|
107
|
-
assert_match %r{timed out}i, e.message,
|
104
|
+
assert_match %r{timed out}i, e.message, "ignore if non-english test run"
|
108
105
|
end
|
109
106
|
assert_client_works(client)
|
110
107
|
close_client(client)
|
111
108
|
assert_new_connections_work
|
112
109
|
end
|
113
110
|
|
114
|
-
it
|
115
|
-
client = new_connection :
|
111
|
+
it "must not timeout per sql batch when not under transaction" do
|
112
|
+
client = new_connection timeout: 2
|
116
113
|
client.execute("WaitFor Delay '00:00:01'").do
|
117
114
|
client.execute("WaitFor Delay '00:00:01'").do
|
118
115
|
client.execute("WaitFor Delay '00:00:01'").do
|
119
116
|
close_client(client)
|
120
117
|
end
|
121
118
|
|
122
|
-
it
|
123
|
-
client = new_connection :
|
119
|
+
it "must not timeout per sql batch when under transaction" do
|
120
|
+
client = new_connection timeout: 2
|
124
121
|
begin
|
125
122
|
client.execute("BEGIN TRANSACTION").do
|
126
123
|
client.execute("WaitFor Delay '00:00:01'").do
|
@@ -132,99 +129,138 @@ class ClientTest < TinyTds::TestCase
|
|
132
129
|
end
|
133
130
|
end
|
134
131
|
|
135
|
-
it
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
132
|
+
it "raises TinyTds exception with tcp socket network failure" do
|
133
|
+
client = new_connection timeout: 2, port: 1234, host: ENV["TOXIPROXY_HOST"]
|
134
|
+
assert_client_works(client)
|
135
|
+
action = lambda { client.execute("waitfor delay '00:00:05'").do }
|
136
|
+
|
137
|
+
# Use toxiproxy to close the TCP socket after 1 second.
|
138
|
+
# We want TinyTds to execute the statement, hit the timeout configured above, and then not be able to use the network to cancel
|
139
|
+
# the network connection needs to close after the sql batch is sent and before the timeout above is hit
|
140
|
+
Toxiproxy[:sqlserver_test].toxic(:slow_close, delay: 1000).apply do
|
144
141
|
assert_raise_tinytds_error(action) do |e|
|
145
142
|
assert_equal 20003, e.db_error_number
|
146
143
|
assert_equal 6, e.severity
|
147
|
-
assert_match %r{timed out}i, e.message,
|
144
|
+
assert_match %r{timed out}i, e.message, "ignore if non-english test run"
|
148
145
|
end
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
146
|
+
end
|
147
|
+
ensure
|
148
|
+
assert_new_connections_work
|
149
|
+
end
|
150
|
+
|
151
|
+
it "raises TinyTds exception with dead connection network failure" do
|
152
|
+
skip if ruby_windows?
|
153
|
+
|
154
|
+
begin
|
155
|
+
client = new_connection timeout: 2, port: 1234, host: ENV["TOXIPROXY_HOST"]
|
156
|
+
assert_client_works(client)
|
157
|
+
action = lambda { client.execute("waitfor delay '00:00:05'").do }
|
158
|
+
|
159
|
+
# Use toxiproxy to close the network connection after 1 second.
|
160
|
+
# We want TinyTds to execute the statement, hit the timeout configured above, and then not be able to use the network to cancel
|
161
|
+
# the network connection needs to close after the sql batch is sent and before the timeout above is hit
|
162
|
+
Toxiproxy[:sqlserver_test].toxic(:timeout, timeout: 1000).apply do
|
163
|
+
assert_raise_tinytds_error(action) do |e|
|
164
|
+
assert_equal 20047, e.db_error_number
|
165
|
+
assert_includes [1, 9], e.severity
|
166
|
+
assert_match %r{dead or not enabled}i, e.message, "ignore if non-english test run"
|
167
|
+
end
|
157
168
|
end
|
158
|
-
|
169
|
+
ensure
|
159
170
|
assert_new_connections_work
|
160
171
|
end
|
161
172
|
end
|
162
173
|
|
163
|
-
it
|
164
|
-
|
165
|
-
|
174
|
+
it "raises TinyTds exception with login timeout" do
|
175
|
+
action = lambda do
|
176
|
+
Toxiproxy[:sqlserver_test].toxic(:timeout, timeout: 0).apply do
|
177
|
+
new_connection login_timeout: 1, port: 1234, host: ENV["TOXIPROXY_HOST"]
|
178
|
+
end
|
179
|
+
end
|
180
|
+
assert_raise_tinytds_error(action) do |e|
|
181
|
+
assert_equal 20003, e.db_error_number
|
182
|
+
assert_equal 6, e.severity
|
183
|
+
assert_match %r{timed out}i, e.message, "ignore if non-english test run"
|
184
|
+
end
|
185
|
+
ensure
|
186
|
+
assert_new_connections_work
|
187
|
+
end
|
188
|
+
|
189
|
+
it "raises TinyTds exception with wrong :username" do
|
190
|
+
skip if ENV["CI"] && sqlserver_azure? # Some issue with db_error_number.
|
191
|
+
options = connection_options username: "willnotwork"
|
166
192
|
action = lambda { new_connection(options) }
|
167
193
|
assert_raise_tinytds_error(action) do |e|
|
168
|
-
assert_equal
|
194
|
+
assert_equal 18456, e.db_error_number
|
169
195
|
assert_equal 14, e.severity
|
170
|
-
assert_match %r{login failed}i, e.message,
|
196
|
+
assert_match %r{login failed}i, e.message, "ignore if non-english test run"
|
171
197
|
end
|
172
198
|
assert_new_connections_work
|
173
199
|
end
|
174
|
-
|
175
200
|
end
|
176
201
|
|
177
|
-
describe
|
178
|
-
|
202
|
+
describe "#parse_username" do
|
179
203
|
let(:client) { @client = new_connection }
|
180
204
|
|
181
|
-
it
|
182
|
-
|
183
|
-
|
205
|
+
it "returns username if azure is not true" do
|
206
|
+
_(
|
207
|
+
client.send(:parse_username, username: "user@abc123.database.windows.net")
|
208
|
+
).must_equal "user@abc123.database.windows.net"
|
184
209
|
end
|
185
210
|
|
186
|
-
it
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
211
|
+
it "returns short username if azure is true" do
|
212
|
+
_(
|
213
|
+
client.send(
|
214
|
+
:parse_username,
|
215
|
+
username: "user@abc123.database.windows.net",
|
216
|
+
host: "abc123.database.windows.net",
|
217
|
+
azure: true
|
218
|
+
)
|
219
|
+
).must_equal "user@abc123"
|
192
220
|
end
|
193
221
|
|
194
|
-
it
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
222
|
+
it "returns full username if azure is false" do
|
223
|
+
_(
|
224
|
+
client.send(
|
225
|
+
:parse_username,
|
226
|
+
username: "user@abc123.database.windows.net",
|
227
|
+
host: "abc123.database.windows.net",
|
228
|
+
azure: false
|
229
|
+
)
|
230
|
+
).must_equal "user@abc123.database.windows.net"
|
200
231
|
end
|
201
232
|
|
202
|
-
it
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
233
|
+
it "returns short username if passed and azure is true" do
|
234
|
+
_(
|
235
|
+
client.send(
|
236
|
+
:parse_username,
|
237
|
+
username: "user@abc123",
|
238
|
+
host: "abc123.database.windows.net",
|
239
|
+
azure: true
|
240
|
+
)
|
241
|
+
).must_equal "user@abc123"
|
208
242
|
end
|
209
243
|
|
210
|
-
it
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
244
|
+
it "returns username with servername if passed and azure is true" do
|
245
|
+
_(
|
246
|
+
client.send(
|
247
|
+
:parse_username,
|
248
|
+
username: "user",
|
249
|
+
host: "abc123.database.windows.net",
|
250
|
+
azure: true
|
251
|
+
)
|
252
|
+
).must_equal "user@abc123"
|
216
253
|
end
|
217
254
|
|
218
|
-
it
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
255
|
+
it "returns username with servername if passed and azure is false" do
|
256
|
+
_(
|
257
|
+
client.send(
|
258
|
+
:parse_username,
|
259
|
+
username: "user",
|
260
|
+
host: "abc123.database.windows.net",
|
261
|
+
azure: false
|
262
|
+
)
|
263
|
+
).must_equal "user"
|
224
264
|
end
|
225
|
-
|
226
265
|
end
|
227
|
-
|
228
|
-
|
229
266
|
end
|
230
|
-
|