1 # -*- encoding: binary -*-
4 class TestMogFresh < Test::Unit::TestCase
6 alias setup setup_mogilefs
7 alias teardown teardown_mogilefs
9 def test_change_device_weight
10 add_host_device_domain
11 assert_equal true, @admin.change_device_weight("me", 1, 50)
12 assert_equal 50, @admin.get_devices(1)[0]["weight"]
15 def test_list_keys_invalid_domain
16 add_host_device_domain
17 domain = @domain + ".non-existent"
18 client = MogileFS::MogileFS.new :hosts => @hosts, :domain => domain
19 assert_raises(MogileFS::Backend::UnregDomainError) do
24 def test_invalid_key_exists
25 add_host_device_domain
26 domain = @domain + ".non-existent"
27 client = MogileFS::MogileFS.new :hosts => @hosts, :domain => domain
28 assert_raises(MogileFS::Backend::UnregDomainError) do
32 client = MogileFS::MogileFS.new :hosts => @hosts, :domain => @domain
33 assert_equal false, client.exist?("non-existent")
36 def test_new_file_info(checksum = nil)
37 add_host_device_domain unless checksum
38 @client = MogileFS::MogileFS.new :hosts => @hosts, :domain => @domain
40 opts = { :info => info }
44 opts[:content_md5] = [ Digest::MD5.digest(content) ].pack('m').rstrip
45 opts[:class] = "check"
47 @client.new_file(key, opts) do |http_file|
51 uris = info.delete(:uris)
52 assert_kind_of Array, uris
53 assert_equal(uris, (@client.get_uris(key) & uris))
54 expect_info = @client.file_info(key, :devices => true)
55 match_keys = %w(class fid key domain length)
56 match_keys << "checksum" if checksum
57 match_keys.each do |field|
58 assert_equal expect_info.delete(field), info.delete(field)
60 assert_operator expect_info.delete("devcount"), :>=, info.delete("devcount")
61 devids = info.delete("devids")
62 assert_equal(devids, (expect_info.delete("devids") & devids))
64 assert info.empty?, info.inspect
65 assert expect_info.empty?, expect_info.inspect
70 def test_new_file_info_checksum
71 add_host_device_domain
72 opts = @admin.get_domains[@domain]["default"]
73 opts["hashtype"] = "MD5"
74 @admin.create_class(@domain, "check", opts)
75 yield_for_monitor_update do
76 tmp = @admin.get_domains[@domain]["check"]
82 warn "skipping checksum test, MogileFS server too old"
85 raise "Unhandled hashtype: #{tmp['hashtype']}"
89 test_new_file_info(:md5)
91 @admin.delete_class(@domain, "check") if @domain
94 def test_create_open_close_opts
95 add_host_device_domain
96 client = MogileFS::MogileFS.new :hosts => @hosts, :domain => @domain
97 socket = client.backend.socket
99 :create_open_args => { :hello => "world" },
100 :create_close_args => { :farewell => "goodnight" },
102 io = client.new_file("foo", args)
103 socket.write "!recent\n"
105 buf << socket.readpartial(666) until buf =~ /\.\r?\n\z/
106 line = buf.split(/\r?\n/).grep(/\screate_open\s/)[0]
107 assert_equal 0, buf.split(/\r?\n/).grep(/\screate_close\s/).size
108 assert_equal 0, buf.split(/\r?\n/).grep(/\sfarewell\s/).size
109 assert_match(/\bhello=world\b/, line)
110 assert_equal 1, io.write('.')
113 socket.write "!recent\n"
115 buf << socket.readpartial(666) until buf =~ /\.\r?\n\z/
116 line = buf.split(/\r?\n/).grep(/\screate_close\s/)[0]
117 assert_match(/\bfarewell=goodnight\b/, line)
120 def test_get_file_data_range
121 add_host_device_domain
122 client = MogileFS::MogileFS.new :hosts => @hosts, :domain => @domain
124 client.store_content("key", "default", data)
126 assert_equal data, client.get_file_data("key")
128 # ensure offset/length matches IO.copy_stream
129 src = Tempfile.new("tmp")
132 [ [1,nil], [1,2], [3,1] ].each do |range|
134 client.get_file_data("key", dst2, *range)
138 if IO.respond_to?(:copy_stream)
139 # ensure we match IO.copy_stream semantics
141 IO.copy_stream(src.to_io, dst, *range)
142 assert_equal dst.string, dst2.string
143 assert_equal dst.string, client.get_file_data("key", nil, *range)
146 assert_equal dst2.string, client.get_file_data("key", nil, *range)
151 def test_new_file_copy_stream_known_length
152 add_host_device_domain
153 opts = { :content_length => 666 }
154 input = StringIO.new("short")
155 client = MogileFS::MogileFS.new :hosts => @hosts, :domain => @domain
156 assert_raises(MogileFS::SizeMismatchError) do
157 client.new_file("copy_stream", opts) do |io|
158 IO.copy_stream(input, io)
162 assert_raises(MogileFS::SizeMismatchError) do
163 client.new_file("copy_stream", opts) do |io|
164 IO.copy_stream(input, io, 666)
167 end if IO.respond_to?(:copy_stream)
169 def test_single_tracker_restart
170 add_host_device_domain
171 client = MogileFS::MogileFS.new :hosts => @hosts, :domain => @domain
174 client.store_content("key", "default", data)
175 listing = client.list_keys
176 assert_instance_of Array, listing
178 # restart the tracker
179 s = TCPSocket.new(@test_host, @tracker_port)
180 s.write "!shutdown\r\n"
181 s.flush # just in case, MRI (at least) syncs by default
187 listing2 = client.list_keys
188 assert_instance_of Array, listing2
189 assert_equal listing, listing2
190 assert_equal([['key'], 'key'], listing)
193 s = TCPSocket.new(@test_host, @tracker_port)
194 s.write "!shutdown\r\n"
195 s.flush # just in case, MRI (at least) syncs by default
198 assert_raises(MogileFS::UnreachableBackendError) { client.list_keys }
201 def test_admin_setup_new_host_and_devices
202 assert_equal [], @admin.get_hosts
203 args = { :ip => @test_host, :port => @mogstored_http_port }
204 @admin.create_host("me", args)
205 yield_for_monitor_update { @admin.get_hosts.empty? or break }
206 hosts = @admin.get_hosts
207 assert_equal 1, hosts.size
208 host = @admin.get_hosts[0]
209 assert_equal "me", host["hostname"]
210 assert_equal @mogstored_http_port, host["http_port"]
211 assert_nil host["http_get_port"]
212 assert_equal @test_host, host["hostip"]
213 assert_kind_of Integer, host["hostid"]
214 assert_equal hosts, @admin.get_hosts(host["hostid"])
216 assert_equal [], @admin.get_devices
219 def test_replicate_now
220 assert_equal({"count" => 0}, @admin.replicate_now)
224 assert_nil @admin.clear_cache
227 def test_create_update_delete_class
228 domain = "rbmogtest#{Time.now.strftime('%Y%m%d%H%M%S')}.#{uuid}"
229 @admin.create_domain(domain)
230 yield_for_monitor_update { @admin.get_domains.include?(domain) and break }
232 @admin.create_class(domain, "klassy", 1)
234 assert_raises(MogileFS::Backend::ClassExistsError) do
235 @admin.create_class(domain, "klassy", 1)
238 @admin.update_class(domain, "klassy",
239 :mindevcount => 1, :replpolicy => "MultipleHosts(1)")
242 yield_for_monitor_update do
243 tmp = @admin.get_domains[domain]["klassy"]
244 break if tmp && tmp["replpolicy"] == "MultipleHosts(1)"
246 assert tmp, "domain did not show up"
247 assert_equal 1, tmp["mindevcount"]
248 assert_equal "MultipleHosts(1)", tmp["replpolicy"]
249 @admin.update_class(domain, "klassy", 2)
251 @admin.delete_class(domain, "klassy") rescue nil
254 def test_device_file_add
255 add_host_device_domain
256 client = MogileFS::MogileFS.new :hosts => @hosts, :domain => @domain
266 assert_equal 20, client.store_file("pipe", nil, r)
267 assert_equal :ok, thr.value
269 assert_equal "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n", client.get_file_data("pipe")