mogilefs-client 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,50 @@
1
+ require 'thread'
2
+ require 'mogilefs'
3
+
4
+ class MogileFS::Pool
5
+
6
+ class BadObjectError < RuntimeError; end
7
+
8
+ def initialize(klass, *args)
9
+ @args = args
10
+ @klass = klass
11
+ @queue = Queue.new
12
+ @objects = []
13
+ end
14
+
15
+ def get
16
+ begin
17
+ object = @queue.pop true
18
+ rescue ThreadError
19
+ object = @klass.new(*@args)
20
+ @objects << object
21
+ end
22
+ return object
23
+ end
24
+
25
+ def put(o)
26
+ raise BadObjectError unless @objects.include? o
27
+ @queue.push o
28
+ purge
29
+ end
30
+
31
+ def use
32
+ object = get
33
+ yield object
34
+ ensure
35
+ put object
36
+ end
37
+
38
+ def purge
39
+ return if @queue.length < 5
40
+ begin
41
+ until @queue.length <= 2 do
42
+ obj = @queue.pop true
43
+ @objects.delete obj
44
+ end
45
+ rescue ThreadError
46
+ end
47
+ end
48
+
49
+ end
50
+
@@ -0,0 +1,55 @@
1
+ require 'test/unit'
2
+
3
+ $TESTING = true
4
+
5
+ require 'mogilefs'
6
+
7
+ class FakeBackend
8
+
9
+ attr_reader :lasterr, :lasterrstr
10
+
11
+ def initialize
12
+ @responses = {}
13
+ @lasterr = nil
14
+ @lasterrstr = nil
15
+ end
16
+
17
+ def method_missing(sym, *args)
18
+ sym = sym.to_s
19
+ if sym =~ /(.*)=$/ then
20
+ @responses[$1] = args.first
21
+ else
22
+ response = @responses[sym]
23
+ case response
24
+ when Hash then
25
+ return response
26
+ when Array then
27
+ @lasterr = response.first
28
+ @lasterrstr = response.last
29
+ return nil
30
+ end
31
+ end
32
+ end
33
+
34
+ end
35
+
36
+ class MogileFS::Client
37
+ attr_writer :readonly
38
+ end
39
+
40
+ class TestMogileFS < Test::Unit::TestCase
41
+
42
+ def setup
43
+ return if self.class == TestMogileFS
44
+ @root = '/mogilefs/test'
45
+ @client = @class.new :hosts => ['kaa:6001'], :domain => 'test',
46
+ :root => @root
47
+ @backend = FakeBackend.new
48
+ @client.instance_variable_set '@backend', @backend
49
+ end
50
+
51
+ def test_nothing
52
+ end
53
+
54
+ end
55
+
@@ -0,0 +1,37 @@
1
+ require 'test/setup'
2
+
3
+ class TestMogileFS__Admin < TestMogileFS
4
+
5
+ def setup
6
+ @class = MogileFS::Admin
7
+ super
8
+ end
9
+
10
+ def test_clean
11
+ res = {"host1_remoteroot"=>"/mnt/mogilefs/rur-1",
12
+ "host1_hostname"=>"rur-1",
13
+ "host1_hostid"=>"1",
14
+ "host1_http_get_port"=>"",
15
+ "host1_altip"=>"",
16
+ "hosts"=>"1",
17
+ "host1_hostip"=>"",
18
+ "host1_http_port"=>"",
19
+ "host1_status"=>"alive",
20
+ "host1_altmask"=>""}
21
+ actual = @client.clean 'hosts', 'host', res
22
+
23
+ expected = [{"status"=>"alive",
24
+ "http_get_port"=>"",
25
+ "http_port"=>"",
26
+ "hostid"=>"1",
27
+ "hostip"=>"",
28
+ "hostname"=>"rur-1",
29
+ "remoteroot"=>"/mnt/mogilefs/rur-1",
30
+ "altip"=>"",
31
+ "altmask"=>""}]
32
+
33
+ assert_equal expected, actual
34
+ end
35
+
36
+ end
37
+
@@ -0,0 +1,208 @@
1
+ require 'test/unit'
2
+
3
+ $TESTING = true
4
+
5
+ require 'mogilefs/backend'
6
+
7
+ class MogileFS::Backend
8
+
9
+ attr_accessor :hosts
10
+ attr_reader :timeout, :dead
11
+ attr_writer :lasterr, :lasterrstr, :socket
12
+
13
+ end
14
+
15
+ class FakeSocket
16
+
17
+ def initialize
18
+ @closed = false
19
+ end
20
+
21
+ def closed?
22
+ @closed
23
+ end
24
+
25
+ def close
26
+ @closed = true
27
+ return nil
28
+ end
29
+
30
+ end
31
+
32
+ class TestBackend < Test::Unit::TestCase
33
+
34
+ def setup
35
+ @backend = MogileFS::Backend.new :hosts => ['localhost:6001']
36
+ end
37
+
38
+ def test_initialize
39
+ assert_raises ArgumentError do MogileFS::Backend.new end
40
+ assert_raises ArgumentError do MogileFS::Backend.new :hosts => [] end
41
+ assert_raises ArgumentError do MogileFS::Backend.new :hosts => [''] end
42
+
43
+ assert_equal ['localhost:6001'], @backend.hosts
44
+ assert_equal 3, @backend.timeout
45
+ assert_equal nil, @backend.lasterr
46
+ assert_equal nil, @backend.lasterrstr
47
+ assert_equal({}, @backend.dead)
48
+
49
+ @backend = MogileFS::Backend.new :hosts => ['localhost:6001'], :timeout => 1
50
+ assert_equal 1, @backend.timeout
51
+ end
52
+
53
+ def test_do_request
54
+ socket_request = ''
55
+ socket = Object.new
56
+ def socket.closed?() false end
57
+ def socket.send(request, flags) return request.length end
58
+ def @backend.select(*args) return [true] end
59
+ def socket.gets() return 'OK 1 you=win' end
60
+
61
+ @backend.instance_variable_set '@socket', socket
62
+
63
+ assert_equal({'you' => 'win'},
64
+ @backend.do_request('go!', { 'fight' => 'team fight!' }))
65
+ end
66
+
67
+ def test_do_request_send_error
68
+ socket_request = ''
69
+ socket = Object.new
70
+ def socket.closed?() false end
71
+ def socket.send(request, flags) raise SystemCallError, 'dummy' end
72
+
73
+ @backend.instance_variable_set '@socket', socket
74
+
75
+ assert_raises RuntimeError do
76
+ @backend.do_request 'go!', { 'fight' => 'team fight!' }
77
+ end
78
+
79
+ assert_equal nil, @backend.instance_variable_get('@socket')
80
+ end
81
+
82
+ def test_do_request_truncated
83
+ socket_request = ''
84
+ socket = Object.new
85
+ def socket.closed?() false end
86
+ def socket.send(request, flags) return request.length - 1 end
87
+
88
+ @backend.instance_variable_set '@socket', socket
89
+
90
+ assert_raises RuntimeError do
91
+ @backend.do_request 'go!', { 'fight' => 'team fight!' }
92
+ end
93
+ end
94
+
95
+ def test_make_request
96
+ assert_equal "go! fight=team+fight%21\r\n",
97
+ @backend.make_request('go!', { 'fight' => 'team fight!' })
98
+ end
99
+
100
+ def test_parse_response
101
+ assert_equal({'foo' => 'bar', 'baz' => 'hoge'},
102
+ @backend.parse_response('OK 1 foo=bar&baz=hoge'))
103
+ assert_equal nil, @backend.parse_response('ERR you totally suck')
104
+ assert_equal 'you', @backend.lasterr
105
+ assert_equal 'totally suck', @backend.lasterrstr
106
+
107
+ assert_raises RuntimeError do
108
+ @backend.parse_response 'garbage'
109
+ end
110
+ end
111
+
112
+ def test_readable_eh_readable
113
+ socket = Object.new
114
+ def socket.closed?() false end
115
+ def @backend.select(*args) return [true] end
116
+ @backend.instance_variable_set '@socket', socket
117
+
118
+ assert_equal true, @backend.readable?
119
+ end
120
+
121
+ def test_readable_eh_not_readable
122
+ socket = Object.new
123
+ def socket.closed?() false end
124
+ def @backend.select(*args) return [] end
125
+ @backend.instance_variable_set '@socket', socket
126
+
127
+ assert_raises MogileFS::UnreadableSocketError do @backend.readable? end
128
+ end
129
+
130
+ def test_socket
131
+ assert_equal({}, @backend.dead)
132
+ assert_raises RuntimeError do @backend.socket end
133
+ assert_equal(['localhost:6001'], @backend.dead.keys)
134
+ end
135
+
136
+ def test_socket_robust
137
+ @backend.hosts = ['localhost:6001', 'localhost:6002']
138
+ def @backend.connect_to(host, port)
139
+ @first = (defined? @first) ? false : true
140
+ raise Errno::ECONNREFUSED if @first
141
+ end
142
+
143
+ assert_equal({}, @backend.dead)
144
+ @backend.socket
145
+ assert_equal false, @backend.dead.keys.empty?
146
+ end
147
+
148
+ def test_shutdown
149
+ fake_socket = FakeSocket.new
150
+ @backend.socket = fake_socket
151
+ assert_equal fake_socket, @backend.socket
152
+ @backend.shutdown
153
+ assert_equal nil, @backend.instance_variable_get(:@socket)
154
+ end
155
+
156
+ def test_url_decode
157
+ assert_equal({"\272z" => "\360opy", "f\000" => "\272r"},
158
+ @backend.url_decode("%baz=%f0opy&f%00=%bar"))
159
+ end
160
+
161
+ def test_url_encode
162
+ params = [["f\000", "\272r"], ["\272z", "\360opy"]]
163
+ assert_equal "f%00=%bar&%baz=%f0opy", @backend.url_encode(params)
164
+ end
165
+
166
+ def test_url_escape # \n for unit_diff
167
+ actual = (0..255).map { |c| @backend.url_escape c.chr }.join "\n"
168
+
169
+ expected = []
170
+ expected.push(*(0..0x1f).map { |c| "%%%0.2x" % c })
171
+ expected << '+'
172
+ expected.push(*(0x21..0x2b).map { |c| "%%%0.2x" % c })
173
+ expected.push(*%w[, - . /])
174
+ expected.push(*('0'..'9'))
175
+ expected.push(*%w[: %3b %3c %3d %3e %3f %40])
176
+ expected.push(*('A'..'Z'))
177
+ expected.push(*%w[%5b \\ %5d %5e _ %60])
178
+ expected.push(*('a'..'z'))
179
+ expected.push(*(0x7b..0xff).map { |c| "%%%0.2x" % c })
180
+
181
+ expected = expected.join "\n"
182
+
183
+ assert_equal expected, actual
184
+ end
185
+
186
+ def test_url_unescape
187
+ input = []
188
+ input.push(*(0..0x1f).map { |c| "%%%0.2x" % c })
189
+ input << '+'
190
+ input.push(*(0x21..0x2b).map { |c| "%%%0.2x" % c })
191
+ input.push(*%w[, - . /])
192
+ input.push(*('0'..'9'))
193
+ input.push(*%w[: %3b %3c %3d %3e %3f %40])
194
+ input.push(*('A'..'Z'))
195
+ input.push(*%w[%5b \\ %5d %5e _ %60])
196
+ input.push(*('a'..'z'))
197
+ input.push(*(0x7b..0xff).map { |c| "%%%0.2x" % c })
198
+
199
+ actual = input.map { |c| @backend.url_unescape c }.join "\n"
200
+
201
+ expected = (0..255).map { |c| c.chr }.join "\n"
202
+ expected.sub! '+', ' '
203
+
204
+ assert_equal expected, actual
205
+ end
206
+
207
+ end
208
+
@@ -0,0 +1,49 @@
1
+ require 'test/unit'
2
+
3
+ $TESTING = true
4
+
5
+ require 'mogilefs'
6
+
7
+ class TestClient < Test::Unit::TestCase
8
+
9
+ def setup
10
+ @client = MogileFS::Client.new :hosts => ['kaa:6001']
11
+ end
12
+
13
+ def test_initialize
14
+ assert_not_nil @client
15
+ assert_instance_of MogileFS::Backend, @client.backend
16
+ assert_equal ['kaa:6001'], @client.hosts
17
+ end
18
+
19
+ def test_err
20
+ @client.backend.lasterr = 'you'
21
+ assert_equal 'you', @client.err
22
+ end
23
+
24
+ def test_errstr
25
+ @client.backend.lasterrstr = 'totally suck'
26
+ assert_equal 'totally suck', @client.errstr
27
+ end
28
+
29
+ def test_reload
30
+ orig_backend = @client.backend
31
+
32
+ @client.hosts = ['ziz:6001']
33
+ @client.reload
34
+
35
+ assert_not_same @client.backend, orig_backend
36
+ assert_equal ['ziz:6001'], @client.backend.hosts
37
+ end
38
+
39
+ def test_readonly_eh_readonly
40
+ client = MogileFS::Client.new :hosts => ['kaa:6001'], :readonly => true
41
+ assert_equal true, client.readonly?
42
+ end
43
+
44
+ def test_readonly_eh_readwrite
45
+ assert_equal false, @client.readonly?
46
+ end
47
+
48
+ end
49
+
@@ -0,0 +1,123 @@
1
+ require 'test/setup'
2
+
3
+ class TestMogileFS__MogileFS < TestMogileFS
4
+
5
+ def setup
6
+ @class = MogileFS::MogileFS
7
+ super
8
+ end
9
+
10
+ def test_initialize
11
+ assert_equal 'test', @client.domain
12
+ assert_equal '/mogilefs/test', @client.root
13
+
14
+ assert_raises ArgumentError do
15
+ MogileFS::MogileFS.new :hosts => ['kaa:6001'], :root => '/mogilefs/test'
16
+ end
17
+ end
18
+
19
+ def test_get_paths
20
+ path1 = 'rur-1/dev1/0/000/000/0000000062.fid'
21
+ path2 = 'rur-2/dev2/0/000/000/0000000062.fid'
22
+
23
+ @backend.get_paths = { 'paths' => 2, 'path1' => path1, 'path2' => path2 }
24
+
25
+ expected = ["#{@root}/#{path1}", "#{@root}/#{path2}"]
26
+
27
+ assert_equal expected, @client.get_paths('key').sort
28
+ end
29
+
30
+ def test_get_paths_unknown_key
31
+ @backend.get_paths = ['unknown_key', '']
32
+
33
+ assert_equal nil, @client.get_paths('key')
34
+ end
35
+
36
+ def test_delete_existing
37
+ @backend.delete = { }
38
+ assert_nothing_raised do
39
+ @client.delete 'no_such_key'
40
+ end
41
+ end
42
+
43
+ def test_delete_nonexisting
44
+ @backend.delete = 'unknown_key', ''
45
+ assert_nothing_raised do
46
+ assert_equal nil, @client.delete('no_such_key')
47
+ end
48
+ end
49
+
50
+ def test_delete_readonly
51
+ @client.readonly = true
52
+ assert_raises RuntimeError do
53
+ @client.delete 'no_such_key'
54
+ end
55
+ end
56
+
57
+ def test_list_keys
58
+ @backend.list_keys = { 'key_count' => 2, 'next_after' => 'new_key_2',
59
+ 'key_1' => 'new_key_1', 'key_2' => 'new_key_2' }
60
+
61
+ keys, next_after = @client.list_keys 'new'
62
+ assert_equal ['new_key_1', 'new_key_2'], keys.sort
63
+ assert_equal 'new_key_2', next_after
64
+ end
65
+
66
+ def test_new_file_http
67
+ @client.readonly = true
68
+ assert_raises RuntimeError do
69
+ @client.new_file 'new_key', 'test'
70
+ end
71
+ end
72
+
73
+ def test_new_file_readonly
74
+ @client.readonly = true
75
+ assert_raises RuntimeError do
76
+ @client.new_file 'new_key', 'test'
77
+ end
78
+ end
79
+
80
+ def test_store_content_readonly
81
+ @client.readonly = true
82
+ assert_raises RuntimeError do
83
+ @client.store_content 'new_key', 'test', nil
84
+ end
85
+ end
86
+
87
+ def test_store_file_readonly
88
+ @client.readonly = true
89
+ assert_raises RuntimeError do
90
+ @client.store_file 'new_key', 'test', nil
91
+ end
92
+ end
93
+
94
+ def test_rename_existing
95
+ @backend.rename = {}
96
+ assert_nothing_raised do
97
+ assert_equal(nil, @client.rename('from_key', 'to_key'))
98
+ end
99
+ end
100
+
101
+ def test_rename_nonexisting
102
+ @backend.rename = 'unknown_key', ''
103
+ assert_nothing_raised do
104
+ assert_equal(nil, @client.rename('from_key', 'to_key'))
105
+ end
106
+ end
107
+
108
+ def test_rename_readonly
109
+ @client.readonly = true
110
+ assert_raises RuntimeError do
111
+ @client.rename 'new_key', 'test'
112
+ end
113
+ end
114
+
115
+ def test_sleep
116
+ @backend.sleep = {}
117
+ assert_nothing_raised do
118
+ assert_equal({}, @client.sleep(2))
119
+ end
120
+ end
121
+
122
+ end
123
+