monetdb 0.1.3 → 0.2.0
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 -13
- data/.travis.yml +5 -0
- data/CHANGELOG.rdoc +4 -0
- data/Gemfile +0 -15
- data/README.rdoc +2 -2
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/lib/monetdb.rb +6 -255
- data/lib/monetdb/connection.rb +94 -412
- data/lib/monetdb/connection/messages.rb +16 -0
- data/lib/monetdb/connection/query.rb +136 -0
- data/lib/monetdb/connection/setup.rb +125 -0
- data/lib/monetdb/error.rb +6 -12
- data/lib/monetdb/version.rb +3 -3
- data/monetdb.gemspec +6 -3
- data/script/console +16 -1
- data/test/test_helper.rb +3 -0
- data/test/test_helper/minitest.rb +7 -0
- data/test/test_helper/simple_connection.rb +13 -0
- data/test/unit/connection/test_messages.rb +48 -0
- data/test/unit/connection/test_query.rb +276 -0
- data/test/unit/connection/test_setup.rb +364 -0
- data/test/unit/test_connection.rb +178 -0
- data/test/unit/test_monetdb.rb +77 -1
- metadata +62 -24
- data/lib/monetdb/core_ext.rb +0 -1
- data/lib/monetdb/core_ext/string.rb +0 -67
- data/lib/monetdb/data.rb +0 -300
- data/lib/monetdb/hasher.rb +0 -40
- data/lib/monetdb/transaction.rb +0 -36
@@ -0,0 +1,276 @@
|
|
1
|
+
require_relative "../../test_helper"
|
2
|
+
|
3
|
+
module Unit
|
4
|
+
module Connection
|
5
|
+
class TestQuery < MiniTest::Test
|
6
|
+
|
7
|
+
class Connection < SimpleConnection
|
8
|
+
include MonetDB::Connection::Messages
|
9
|
+
include MonetDB::Connection::Query
|
10
|
+
end
|
11
|
+
|
12
|
+
describe MonetDB::Connection::Query do
|
13
|
+
before do
|
14
|
+
@connection = Connection.new
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "#extract_headers!" do
|
18
|
+
it "returns an array with delegated return values" do
|
19
|
+
response, foo, bar = mock, mock, mock
|
20
|
+
|
21
|
+
@connection.expects(:parse_query_header!).with(response).returns(foo)
|
22
|
+
@connection.expects(:parse_scheme_header!).with(response).returns(bar)
|
23
|
+
|
24
|
+
assert_equal [foo, bar], @connection.send(:extract_headers!, response)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#parse_query_header!" do
|
29
|
+
describe "containing an error message" do
|
30
|
+
it "raises a query error" do
|
31
|
+
assert_raises MonetDB::QueryError do
|
32
|
+
@connection.send(:parse_query_header!, ["!epicfail", "foo"])
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "when absent in response" do
|
38
|
+
it "raises a query error" do
|
39
|
+
assert_raises MonetDB::QueryError do
|
40
|
+
@connection.send(:parse_query_header!, ["$money", "foo"])
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "when present in response" do
|
46
|
+
it "extracts the first line from the response and returns to_query_header_hash" do
|
47
|
+
response = [
|
48
|
+
"& 1 8 1982 0",
|
49
|
+
"% foo",
|
50
|
+
"% bar",
|
51
|
+
"[ 19, 82 ]",
|
52
|
+
"[ 20, 47 ]"
|
53
|
+
]
|
54
|
+
|
55
|
+
@connection.expects(:to_query_header_hash).returns(hash = "hash")
|
56
|
+
assert_equal hash, @connection.send(:parse_query_header!, response)
|
57
|
+
assert_equal [
|
58
|
+
"% foo",
|
59
|
+
"% bar",
|
60
|
+
"[ 19, 82 ]",
|
61
|
+
"[ 20, 47 ]"
|
62
|
+
], response
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "#to_query_header_hash" do
|
68
|
+
describe "when Q_TABLE header" do
|
69
|
+
it "returns a table header hash" do
|
70
|
+
assert_equal({
|
71
|
+
:type => "1",
|
72
|
+
:id => 0,
|
73
|
+
:rows => 1947,
|
74
|
+
:columns => 8,
|
75
|
+
:returned => 2014
|
76
|
+
}, @connection.send(:to_query_header_hash, "&1 0 1947 8 2014"))
|
77
|
+
end
|
78
|
+
end
|
79
|
+
describe "when Q_BLOCK header" do
|
80
|
+
it "returns a block header hash" do
|
81
|
+
assert_equal({
|
82
|
+
:type => "6",
|
83
|
+
:id => 0,
|
84
|
+
:columns => 10,
|
85
|
+
:remains => 179,
|
86
|
+
:offset => 100
|
87
|
+
}, @connection.send(:to_query_header_hash, "&6 0 10 179 100"))
|
88
|
+
end
|
89
|
+
end
|
90
|
+
describe "when unknown header" do
|
91
|
+
it "returns a simple hash with just the type" do
|
92
|
+
assert_equal({:type => "0"}, @connection.send(:to_query_header_hash, "&0 1 2 3"))
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe "#parse_scheme_header!" do
|
98
|
+
describe "when present in response" do
|
99
|
+
it "extracts scheme related lines from the response and returns to_scheme_header_hash" do
|
100
|
+
response = [
|
101
|
+
"% foo",
|
102
|
+
"% bar",
|
103
|
+
"[ 19, 82 ]",
|
104
|
+
"[ 20, 47 ]"
|
105
|
+
]
|
106
|
+
|
107
|
+
@connection.expects(:to_scheme_header_hash).returns(hash = "hash")
|
108
|
+
assert_equal hash, @connection.send(:parse_scheme_header!, response)
|
109
|
+
assert_equal [
|
110
|
+
"[ 19, 82 ]",
|
111
|
+
"[ 20, 47 ]"
|
112
|
+
], response
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe "when absent in response" do
|
117
|
+
it "returns nil" do
|
118
|
+
response = [
|
119
|
+
"[ 19, 82 ]",
|
120
|
+
"% foo bar",
|
121
|
+
"[ 20, 47 ]"
|
122
|
+
]
|
123
|
+
assert_nil @connection.send(:parse_scheme_header!, response)
|
124
|
+
assert_equal [
|
125
|
+
"[ 19, 82 ]",
|
126
|
+
"% foo bar",
|
127
|
+
"[ 20, 47 ]"
|
128
|
+
], response
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
describe "#to_scheme_header_hash" do
|
134
|
+
it "returns a frozen hash" do
|
135
|
+
header = [
|
136
|
+
%w(foo_bars baz_quxs paul_engels),
|
137
|
+
%w(foo bar baz qux),
|
138
|
+
%w(tinyint varchar integer float),
|
139
|
+
%w(1 9 8 2)
|
140
|
+
]
|
141
|
+
|
142
|
+
hash = @connection.send(:to_scheme_header_hash, header)
|
143
|
+
|
144
|
+
assert_equal true, hash.frozen?
|
145
|
+
assert_equal({
|
146
|
+
:table_name => "foo_bars",
|
147
|
+
:column_names => %w(foo bar baz qux),
|
148
|
+
:column_types => [:tinyint, :varchar, :integer, :float],
|
149
|
+
:column_lengths => [1, 9, 8, 2]
|
150
|
+
}, hash)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
describe "#parse_rows" do
|
155
|
+
it "returns an array of hashes" do
|
156
|
+
table_header = {
|
157
|
+
:column_types => [:varchar, :date, :double]
|
158
|
+
}
|
159
|
+
|
160
|
+
response = [
|
161
|
+
"[ \"Paul Engel\",\t1982-08-01,\t19.82\t]",
|
162
|
+
"[ \"Ken Adams\",\t1980-10-13,\t20.47\t]"
|
163
|
+
].join("\n")
|
164
|
+
|
165
|
+
assert_equal [
|
166
|
+
["Paul Engel", Date.parse("1982-08-01"), 19.82],
|
167
|
+
["Ken Adams", Date.parse("1980-10-13"), 20.47]
|
168
|
+
], @connection.send(:parse_rows, table_header, response)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
describe "#parse_value" do
|
173
|
+
describe "when NULL" do
|
174
|
+
it "returns nil" do
|
175
|
+
assert_nil @connection.send(:parse_value, :varchar, "NULL")
|
176
|
+
assert_nil @connection.send(:parse_value, :text, "NULL")
|
177
|
+
assert_nil @connection.send(:parse_value, :int, "NULL")
|
178
|
+
assert_nil @connection.send(:parse_value, :smallint, "NULL")
|
179
|
+
assert_nil @connection.send(:parse_value, :bigint, "NULL")
|
180
|
+
assert_nil @connection.send(:parse_value, :double, "NULL")
|
181
|
+
assert_nil @connection.send(:parse_value, :float, "NULL")
|
182
|
+
assert_nil @connection.send(:parse_value, :real, "NULL")
|
183
|
+
assert_nil @connection.send(:parse_value, :date, "NULL")
|
184
|
+
assert_nil @connection.send(:parse_value, :timestamp, "NULL")
|
185
|
+
assert_nil @connection.send(:parse_value, :tinyint, "NULL")
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
describe "when not NULL" do
|
190
|
+
describe "when is type valid" do
|
191
|
+
it "delegates to the appropiate parse method" do
|
192
|
+
value = mock
|
193
|
+
|
194
|
+
@connection.expects(:parse_string_value).with(value)
|
195
|
+
@connection.send(:parse_value, :varchar, value)
|
196
|
+
|
197
|
+
@connection.expects(:parse_string_value).with(value)
|
198
|
+
@connection.send(:parse_value, :text, value)
|
199
|
+
|
200
|
+
@connection.expects(:parse_integer_value).with(value)
|
201
|
+
@connection.send(:parse_value, :int, value)
|
202
|
+
|
203
|
+
@connection.expects(:parse_integer_value).with(value)
|
204
|
+
@connection.send(:parse_value, :smallint, value)
|
205
|
+
|
206
|
+
@connection.expects(:parse_integer_value).with(value)
|
207
|
+
@connection.send(:parse_value, :bigint, value)
|
208
|
+
|
209
|
+
@connection.expects(:parse_float_value).with(value)
|
210
|
+
@connection.send(:parse_value, :float, value)
|
211
|
+
|
212
|
+
@connection.expects(:parse_float_value).with(value)
|
213
|
+
@connection.send(:parse_value, :real, value)
|
214
|
+
|
215
|
+
@connection.expects(:parse_date_value).with(value)
|
216
|
+
@connection.send(:parse_value, :date, value)
|
217
|
+
|
218
|
+
@connection.expects(:parse_date_time_value).with(value)
|
219
|
+
@connection.send(:parse_value, :timestamp, value)
|
220
|
+
|
221
|
+
@connection.expects(:parse_boolean_value).with(value)
|
222
|
+
@connection.send(:parse_value, :tinyint, value)
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
describe "when is type invalid" do
|
227
|
+
it "raises a not implemented error" do
|
228
|
+
assert_raises NotImplementedError do
|
229
|
+
@connection.send(:parse_value, :foo, mock)
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
describe "#parse_string_value" do
|
237
|
+
it "returns a string" do
|
238
|
+
assert_equal "Paul Engel", @connection.send(:parse_string_value, "\"Paul Engel\"")
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
describe "#parse_integer_value" do
|
243
|
+
it "returns an integer" do
|
244
|
+
assert_equal 1982, @connection.send(:parse_integer_value, "1982")
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
describe "#parse_float_value" do
|
249
|
+
it "returns a float" do
|
250
|
+
assert_equal 19.82, @connection.send(:parse_float_value, "19.82")
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
describe "#parse_date_value" do
|
255
|
+
it "returns a Date instance" do
|
256
|
+
assert_equal Date.parse("1982-08-01"), @connection.send(:parse_date_value, "1982-08-01")
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
describe "#parse_date_time_value" do
|
261
|
+
it "returns a Time instance" do
|
262
|
+
assert_equal Time.parse("1982-08-01 18:19:47"), @connection.send(:parse_date_time_value, "1982-08-01 18:19:47.0000")
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
describe "#parse_boolean_value" do
|
267
|
+
it "returns a boolean" do
|
268
|
+
assert_equal false, @connection.send(:parse_boolean_value, "0")
|
269
|
+
assert_equal true, @connection.send(:parse_boolean_value, "1")
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
end
|
275
|
+
end
|
276
|
+
end
|
@@ -0,0 +1,364 @@
|
|
1
|
+
require_relative "../../test_helper"
|
2
|
+
|
3
|
+
module Unit
|
4
|
+
module Connection
|
5
|
+
class TestSetup < MiniTest::Test
|
6
|
+
|
7
|
+
class Connection < SimpleConnection
|
8
|
+
include MonetDB::Connection::Messages
|
9
|
+
include MonetDB::Connection::Setup
|
10
|
+
end
|
11
|
+
|
12
|
+
describe MonetDB::Connection::Setup do
|
13
|
+
before do
|
14
|
+
@connection = Connection.new
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "#setup" do
|
18
|
+
it "obtains the server challenge, sets up the timezone and reply size" do
|
19
|
+
@connection.expects(:authenticate)
|
20
|
+
@connection.expects(:set_timezone_interval)
|
21
|
+
@connection.expects(:set_reply_size)
|
22
|
+
@connection.send(:setup)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#authenticate" do
|
27
|
+
before do
|
28
|
+
@connection.expects(:obtain_server_challenge!)
|
29
|
+
@connection.expects(:authentication_string).returns(auth_string = "<authentication_string>")
|
30
|
+
@connection.expects(:write).with(auth_string)
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "when success" do
|
34
|
+
it "returns true" do
|
35
|
+
@connection.expects(:read).returns("")
|
36
|
+
@connection.send(:authenticate)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "when redirect" do
|
41
|
+
it "authenticates using the redirect" do
|
42
|
+
@connection.expects(:read).returns(response = "^^mapi:redirect")
|
43
|
+
@connection.expects(:authentication_redirect).with(response)
|
44
|
+
@connection.send(:authenticate)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "when fail" do
|
49
|
+
it "raises an authentication error" do
|
50
|
+
@connection.expects(:read).returns("!epicfail")
|
51
|
+
assert_raises MonetDB::AuthenticationError do
|
52
|
+
@connection.send(:authenticate)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "#obtain_server_challenge!" do
|
59
|
+
it "updates the config and validates it" do
|
60
|
+
@connection.expects(:server_challenge).returns(:foo => "bar", :baz => "qux")
|
61
|
+
@connection.expects(:assert_supported_protocol!)
|
62
|
+
@connection.expects(:select_supported_auth_type!)
|
63
|
+
|
64
|
+
assert_equal({
|
65
|
+
:host => "localhost",
|
66
|
+
:port => 50000,
|
67
|
+
:username => "monetdb",
|
68
|
+
:password => "monetdb"
|
69
|
+
}, @connection.instance_variable_get(:@config))
|
70
|
+
|
71
|
+
@connection.send(:obtain_server_challenge!)
|
72
|
+
|
73
|
+
assert_equal({
|
74
|
+
:host => "localhost",
|
75
|
+
:port => 50000,
|
76
|
+
:username => "monetdb",
|
77
|
+
:password => "monetdb",
|
78
|
+
:foo => "bar",
|
79
|
+
:baz => "qux"
|
80
|
+
}, @connection.instance_variable_get(:@config))
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe "#server_challenge" do
|
85
|
+
it "returns the server challenge config" do
|
86
|
+
response = "<salt>:<server_name>:9:MD5,SHA512:<server_endianness>:SHA1"
|
87
|
+
@connection.expects(:read).returns(response)
|
88
|
+
assert_equal({
|
89
|
+
:salt => "<salt>",
|
90
|
+
:server_name => "<server_name>",
|
91
|
+
:protocol => "9",
|
92
|
+
:auth_types => "MD5,SHA512",
|
93
|
+
:server_endianness => "<server_endianness>",
|
94
|
+
:password_digest_method => "SHA1"
|
95
|
+
}, @connection.send(:server_challenge))
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "#assert_supported_protocol!" do
|
100
|
+
describe "when supporting one of the server protocols" do
|
101
|
+
it "returns nil" do
|
102
|
+
@connection.instance_variable_get(:@config)[:protocol] = MonetDB::Connection::MAPI_V8
|
103
|
+
assert_nil @connection.send(:assert_supported_protocol!)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe "when not supporting any of the server protocols" do
|
108
|
+
it "raises a protocol error" do
|
109
|
+
@connection.instance_variable_get(:@config)[:protocol] = "FOO"
|
110
|
+
assert_raises MonetDB::ProtocolError do
|
111
|
+
@connection.send(:assert_supported_protocol!)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe "#select_supported_auth_type!" do
|
118
|
+
describe "when supporting one of the server authentication types" do
|
119
|
+
it "selects a supported authentication type" do
|
120
|
+
config = @connection.instance_variable_get(:@config)
|
121
|
+
auth_md5 = MonetDB::Connection::AUTH_MD5
|
122
|
+
|
123
|
+
config[:auth_types] = "FOO,#{auth_md5},BAR"
|
124
|
+
assert_nil config[:auth_type]
|
125
|
+
|
126
|
+
@connection.send(:select_supported_auth_type!)
|
127
|
+
assert_equal auth_md5, config[:auth_type]
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe "when not supporting any of the server authentication types" do
|
132
|
+
it "raises an authentication error" do
|
133
|
+
response = "<salt>:<server_name>:9:CRYPT:<server_endianness>:SHA1"
|
134
|
+
@connection.expects(:read).returns(response)
|
135
|
+
assert_raises MonetDB::AuthenticationError do
|
136
|
+
@connection.send(:obtain_server_challenge!)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
describe "#authentication_string" do
|
143
|
+
before do
|
144
|
+
@endianness = MonetDB::Connection::ENDIANNESS
|
145
|
+
@lang = MonetDB::Connection::LANG
|
146
|
+
@connection.instance_variable_set :@config, {
|
147
|
+
:database => "db",
|
148
|
+
:username => "paul",
|
149
|
+
:password => "mysecret",
|
150
|
+
:salt => "kitchen",
|
151
|
+
:password_digest_method => "MD5"
|
152
|
+
}
|
153
|
+
end
|
154
|
+
|
155
|
+
describe "MAPI V8 protocol" do
|
156
|
+
before do
|
157
|
+
@connection.instance_variable_get(:@config)[:protocol] = MonetDB::Connection::MAPI_V8
|
158
|
+
end
|
159
|
+
|
160
|
+
describe "when using digests" do
|
161
|
+
it "returns an authentication string with a digest hashsum" do
|
162
|
+
@connection.instance_variable_get(:@config)[:auth_type] = "MD5"
|
163
|
+
hashsum = "ec2c417dbdaa6fec77eef74e8c2524b9"
|
164
|
+
assert_equal "#{@endianness}:paul:{MD5}#{hashsum}:#{@lang}:db:", @connection.send(:authentication_string)
|
165
|
+
|
166
|
+
@connection.instance_variable_get(:@config)[:auth_type] = "SHA1"
|
167
|
+
hashsum = "10cbdc8ea82154bbfe64df5265a2f35118b51a18"
|
168
|
+
assert_equal "#{@endianness}:paul:{SHA1}#{hashsum}:#{@lang}:db:", @connection.send(:authentication_string)
|
169
|
+
|
170
|
+
@connection.instance_variable_get(:@config)[:auth_type] = "SHA512"
|
171
|
+
hashsum = "8527a8feaa8ea3e538b16a1a40e76176edb725b29bb8989ec4800de625f6b1d3569eb7fae49b0b54ae33bbf055e462a769582d0f02a18181e5dac1b106710d98"
|
172
|
+
assert_equal "#{@endianness}:paul:{SHA512}#{hashsum}:#{@lang}:db:", @connection.send(:authentication_string)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
describe "when plain authentication type" do
|
177
|
+
it "returns an authentication string with a plain hashsum" do
|
178
|
+
@connection.instance_variable_get(:@config)[:auth_type] = "PLAIN"
|
179
|
+
assert_equal "#{@endianness}:paul:{PLAIN}mysecretkitchen:#{@lang}:db:", @connection.send(:authentication_string)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
describe "when non-supported authentication type" do
|
184
|
+
it "returns an authentication string without hashsum" do
|
185
|
+
assert_equal "#{@endianness}:paul:{}:#{@lang}:db:", @connection.send(:authentication_string)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
describe "MAPI V9 protocol" do
|
191
|
+
before do
|
192
|
+
@connection.instance_variable_get(:@config)[:protocol] = MonetDB::Connection::MAPI_V9
|
193
|
+
@connection.instance_variable_get(:@config)[:password_digest_method] = "MD5"
|
194
|
+
end
|
195
|
+
|
196
|
+
describe "when using digests" do
|
197
|
+
it "returns an authentication string with a digest hashsum" do
|
198
|
+
@connection.instance_variable_get(:@config)[:auth_type] = "MD5"
|
199
|
+
hashsum = "2c89f883c0a9e30f58585f15adeb0500"
|
200
|
+
assert_equal "#{@endianness}:paul:{MD5}#{hashsum}:#{@lang}:db:", @connection.send(:authentication_string)
|
201
|
+
|
202
|
+
@connection.instance_variable_get(:@config)[:auth_type] = "SHA1"
|
203
|
+
hashsum = "51f0d237aedd38ad10f3348ecaa95d1d9fc7d7fd"
|
204
|
+
assert_equal "#{@endianness}:paul:{SHA1}#{hashsum}:#{@lang}:db:", @connection.send(:authentication_string)
|
205
|
+
|
206
|
+
@connection.instance_variable_get(:@config)[:auth_type] = "SHA512"
|
207
|
+
hashsum = "cf623a200ef12a7413835745bd0287cba478f1eb275c57137f7bdcea20ec10897544ad7a45647c3b814ff9e9e2fb187e6277fe2f994b23bb7d09f2141f83fffa"
|
208
|
+
assert_equal "#{@endianness}:paul:{SHA512}#{hashsum}:#{@lang}:db:", @connection.send(:authentication_string)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
describe "when plain authentication type" do
|
213
|
+
it "returns an authentication string with a plain hashsum" do
|
214
|
+
@connection.instance_variable_get(:@config)[:auth_type] = "PLAIN"
|
215
|
+
assert_equal "#{@endianness}:paul:{PLAIN}mysecretkitchen:#{@lang}:db:", @connection.send(:authentication_string)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
describe "when non-supported authentication type" do
|
220
|
+
it "returns an authentication string without hashsum" do
|
221
|
+
assert_equal "#{@endianness}:paul:{}:#{@lang}:db:", @connection.send(:authentication_string)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
describe "#hexdigest" do
|
228
|
+
it "returns the hexdigest using the passed method and value" do
|
229
|
+
assert_equal "acbd18db4cc2f85cedef654fccc4a4d8", @connection.send(:hexdigest, "MD5", "foo")
|
230
|
+
assert_equal "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33", @connection.send(:hexdigest, "SHA1", "foo")
|
231
|
+
assert_equal "f7fbba6e0636f890e56fbbf3283e524c6fa3204ae298382d624741d0dc6638326e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7", @connection.send(:hexdigest, "SHA512", "foo")
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
describe "#authentication_redirect" do
|
236
|
+
describe "without a MAPI redirect" do
|
237
|
+
it "raises an authentication error" do
|
238
|
+
assert_raises MonetDB::AuthenticationError do
|
239
|
+
@connection.send(:authentication_redirect, "^foobar:bazqux")
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
describe "without a valid redirect URI" do
|
245
|
+
it "raises an authentication error" do
|
246
|
+
URI.expects(:split).raises(URI::InvalidURIError)
|
247
|
+
assert_raises MonetDB::AuthenticationError do
|
248
|
+
@connection.send(:authentication_redirect, "^mapi:foobar")
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
describe "with 'merovingian' scheme" do
|
254
|
+
it "retries to authenticate" do
|
255
|
+
@connection.expects(:authenticate)
|
256
|
+
@connection.send(:authentication_redirect, "^mapi:merovingian://foobar")
|
257
|
+
end
|
258
|
+
|
259
|
+
describe "when too many retries" do
|
260
|
+
it "raises an authentication error" do
|
261
|
+
@connection.expects(:obtain_server_challenge!).times(5)
|
262
|
+
@connection.expects(:write).times(5)
|
263
|
+
@connection.expects(:read).times(5).returns(response = "^mapi:merovingian://foobar")
|
264
|
+
assert_raises MonetDB::AuthenticationError do
|
265
|
+
@connection.send(:authentication_redirect, response)
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
describe "with 'monetdb' scheme" do
|
272
|
+
it "raises an authentication error" do
|
273
|
+
@connection.expects(:connect)
|
274
|
+
@connection.send(:authentication_redirect, "^mapi:monetdb://ghost:1982")
|
275
|
+
assert_equal "ghost", @connection.send(:config)[:host]
|
276
|
+
assert_equal "1982", @connection.send(:config)[:port]
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
describe "without a supported server name" do
|
281
|
+
it "raises an authentication error" do
|
282
|
+
assert_raises MonetDB::AuthenticationError do
|
283
|
+
@connection.send(:authentication_redirect, "^mapi:foobar")
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
describe "#set_timezone_interval" do
|
290
|
+
describe "when not already set" do
|
291
|
+
describe "when success" do
|
292
|
+
it "returns true" do
|
293
|
+
time = mock
|
294
|
+
time.expects(:gmt_offset).returns(7200)
|
295
|
+
Time.expects(:now).returns(time)
|
296
|
+
|
297
|
+
@connection.expects(:write).with("sSET TIME ZONE INTERVAL '+02:00' HOUR TO MINUTE;")
|
298
|
+
@connection.expects(:read).returns("")
|
299
|
+
assert_equal true, @connection.send(:set_timezone_interval)
|
300
|
+
|
301
|
+
@connection.instance_variable_set(:@timezone_interval_set, false)
|
302
|
+
|
303
|
+
time = mock
|
304
|
+
time.expects(:gmt_offset).returns(36000)
|
305
|
+
Time.expects(:now).returns(time)
|
306
|
+
|
307
|
+
@connection.expects(:write).with("sSET TIME ZONE INTERVAL '+10:00' HOUR TO MINUTE;")
|
308
|
+
@connection.expects(:read).returns("")
|
309
|
+
assert_equal true, @connection.send(:set_timezone_interval)
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
describe "when fail" do
|
314
|
+
it "raises a command error" do
|
315
|
+
@connection.expects(:write)
|
316
|
+
@connection.expects(:read).returns("!epicfail")
|
317
|
+
assert_raises MonetDB::CommandError do
|
318
|
+
@connection.send(:set_timezone_interval)
|
319
|
+
end
|
320
|
+
end
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
describe "when already set" do
|
325
|
+
it "returns false" do
|
326
|
+
@connection.instance_variable_set(:@timezone_interval_set, true)
|
327
|
+
assert_equal false, @connection.send(:set_timezone_interval)
|
328
|
+
end
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
332
|
+
describe "#set_reply_size" do
|
333
|
+
describe "when not already set" do
|
334
|
+
describe "when success" do
|
335
|
+
it "returns true" do
|
336
|
+
@connection.expects(:write).with("Xreply_size #{MonetDB::Connection::REPLY_SIZE}\n")
|
337
|
+
@connection.expects(:read).returns("")
|
338
|
+
assert_equal true, @connection.send(:set_reply_size)
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
describe "when fail" do
|
343
|
+
it "raises a command error" do
|
344
|
+
@connection.expects(:write)
|
345
|
+
@connection.expects(:read).returns("!epicfail")
|
346
|
+
assert_raises MonetDB::CommandError do
|
347
|
+
@connection.send(:set_reply_size)
|
348
|
+
end
|
349
|
+
end
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
describe "when already set" do
|
354
|
+
it "returns false" do
|
355
|
+
@connection.instance_variable_set(:@reply_size_set, true)
|
356
|
+
assert_equal false, @connection.send(:set_reply_size)
|
357
|
+
end
|
358
|
+
end
|
359
|
+
end
|
360
|
+
end
|
361
|
+
|
362
|
+
end
|
363
|
+
end
|
364
|
+
end
|