new_file/common: simplify empty class declarations
[ruby-mogilefs-client.git] / test / test_fresh.rb
blobff7bae6854a915aed57fe17d1344e0c01c9d82ae
1 # -*- encoding: binary -*-
2 require "./test/fresh"
4 class TestMogFresh < Test::Unit::TestCase
5   include TestFreshSetup
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"]
13   end
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
20       client.list_keys
21     end
22   end
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
29       client.exist?("FOO")
30     end
32     client = MogileFS::MogileFS.new :hosts => @hosts, :domain => @domain
33     assert_equal false, client.exist?("non-existent")
34   end
36   def test_new_file_info(checksum = nil)
37     add_host_device_domain unless checksum
38     @client = MogileFS::MogileFS.new :hosts => @hosts, :domain => @domain
39     info = {}
40     opts = { :info => info }
41     key = "new_file_info"
42     content = "ZZZZ"
43     if checksum
44       opts[:content_md5] = [ Digest::MD5.digest(content) ].pack('m').rstrip
45       opts[:class] = "check"
46     end
47     @client.new_file(key, opts) do |http_file|
48       http_file << content
49     end
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)
59     end
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
66   ensure
67     @client.delete(key)
68   end
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"]
77       if tmp
78         case tmp["hashtype"]
79         when "MD5"
80           break
81         when nil
82           warn "skipping checksum test, MogileFS server too old"
83           return
84         else
85           raise "Unhandled hashtype: #{tmp['hashtype']}"
86         end
87       end
88     end
89     test_new_file_info(:md5)
90   ensure
91     @admin.delete_class(@domain, "check") if @domain
92   end
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
98     args = {
99       :create_open_args => { :hello => "world" },
100       :create_close_args => { :farewell => "goodnight" },
101     }
102     io = client.new_file("foo", args)
103     socket.write "!recent\n"
104     buf = ""
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('.')
111     assert_nil io.close
113     socket.write "!recent\n"
114     buf = ""
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)
118   end
120   def test_get_file_data_range
121     add_host_device_domain
122     client = MogileFS::MogileFS.new :hosts => @hosts, :domain => @domain
123     data = "data"
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")
130     src.write(data)
131     src.flush
132     [ [1,nil], [1,2], [3,1] ].each do |range|
133       dst2 = StringIO.new
134       client.get_file_data("key", dst2, *range)
136       src.rewind
138       if IO.respond_to?(:copy_stream)
139         # ensure we match IO.copy_stream semantics
140         dst = StringIO.new
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)
144       end
146       assert_equal dst2.string, client.get_file_data("key", nil, *range)
147     end
148     src.close!
149   end
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)
159       end
160     end
162     assert_raises(MogileFS::SizeMismatchError) do
163       client.new_file("copy_stream", opts) do |io|
164         IO.copy_stream(input, io, 666)
165       end
166     end
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
173     data = "data"
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
182     assert_nil s.gets
184     start_tracker
186     # transparent retry
187     listing2 = client.list_keys
188     assert_instance_of Array, listing2
189     assert_equal listing, listing2
190     assert_equal([['key'], 'key'], listing)
192     # kill the tracker
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
196     assert_nil s.gets
197     @mogilefsd_pid = nil
198     assert_raises(MogileFS::UnreachableBackendError) { client.list_keys }
199   end
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
217   end
219   def test_replicate_now
220     assert_equal({"count" => 0}, @admin.replicate_now)
221   end
223   def test_clear_cache
224     assert_nil @admin.clear_cache
225   end
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)
236     end
238     @admin.update_class(domain, "klassy",
239                         :mindevcount => 1, :replpolicy => "MultipleHosts(1)")
241     tmp = nil
242     yield_for_monitor_update do
243       tmp = @admin.get_domains[domain]["klassy"]
244       break if tmp && tmp["replpolicy"] == "MultipleHosts(1)"
245     end
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)
250     ensure
251       @admin.delete_class(domain, "klassy") rescue nil
252   end
254   def test_device_file_add
255     add_host_device_domain
256     client = MogileFS::MogileFS.new :hosts => @hosts, :domain => @domain
257     r, w = IO.pipe
258     thr = Thread.new do
259       (0..9).each do |i|
260         sleep 0.05
261         w.write("#{i}\n")
262       end
263       w.close
264       :ok
265     end
266     assert_equal 20, client.store_file("pipe", nil, r)
267     assert_equal :ok, thr.value
268     r.close
269     assert_equal "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n", client.get_file_data("pipe")
270   end