client: small speedup for list_keys_verbose
[ruby-mogilefs-client.git] / test / fresh.rb
blob749673f4b3de4601a3ccd5746b714e9a32664bb5
1 # -*- encoding: binary -*-
2 require "./test/exec"
3 require "tmpdir"
4 require "fileutils"
5 require "net/http"
7 module TestFreshSetup
8   include TestExec
10   def setup
11     setup_mogilefs
12   end
14   def setup_mogilefs(plugins = nil)
15     @test_host = "127.0.0.1"
16     setup_mogstored
17     @tracker = TCPServer.new(@test_host, 0)
18     @tracker_port = @tracker.addr[1]
20     @dbname = Tempfile.new(["mogfresh", ".sqlite3"])
21     @mogilefsd_conf = Tempfile.new(["mogilefsd", "conf"])
22     @mogilefsd_pid = Tempfile.new(["mogilefsd", "pid"])
24     cmd = %w(mogdbsetup --yes --type=SQLite --dbname) << @dbname.path
25     x!(*cmd)
27     @mogilefsd_conf.puts "db_dsn DBI:SQLite:#{@dbname.path}"
28     @mogilefsd_conf.write <<EOF
29 conf_port #@tracker_port
30 listen #@test_host
31 pidfile #{@mogilefsd_pid.path}
32 replicate_jobs 1
33 fsck_jobs 1
34 query_jobs 1
35 mogstored_stream_port #{@mogstored_mgmt_port}
36 node_timeout 10
37 EOF
38     @mogilefsd_conf.flush
40     @trackers = @hosts = [ "#@test_host:#@tracker_port" ]
41     @tracker.close
42     x!("mogilefsd", "--daemon", "--config=#{@mogilefsd_conf.path}")
43     wait_for_port @tracker_port
44     @admin = MogileFS::Admin.new(:hosts => @hosts)
45     50.times do
46       break if File.size(@mogstored_pid.path) > 0
47       sleep 0.1
48     end
49   end
51   def wait_for_port(port)
52     tries = 50
53     begin
54       TCPSocket.new(@test_host, port).close
55       return
56     rescue
57       sleep 0.1
58     end while (tries -= 1) > 0
59     raise "#@test_host:#{port} never became ready"
60   end
62   def test_admin_setup_new_host_and_devices
63     assert_equal [], @admin.get_hosts
64     args = { :ip => @test_host, :port => @mogstored_http_port }
65     @admin.create_host("me", args)
66     yield_for_monitor_update { @admin.get_hosts.empty? or break }
67     hosts = @admin.get_hosts
68     assert_equal 1, hosts.size
69     host = @admin.get_hosts[0]
70     assert_equal "me", host["hostname"]
71     assert_equal @mogstored_http_port, host["http_port"]
72     assert_nil host["http_get_port"]
73     assert_equal @test_host, host["hostip"]
74     assert_kind_of Integer, host["hostid"]
75     assert_equal hosts, @admin.get_hosts(host["hostid"])
77     assert_equal [], @admin.get_devices
78   end
80   def test_replicate_now
81     assert_equal({"count" => 0}, @admin.replicate_now)
82   end
84   def test_clear_cache
85     assert_nil @admin.clear_cache
86   end
88   def test_create_update_delete_class
89     domain = "rbmogtest#{Time.now.strftime('%Y%m%d%H%M%S')}.#{uuid}"
90     @admin.create_domain(domain)
91     yield_for_monitor_update { @admin.get_domains.include?(domain) and break }
93     assert_nothing_raised do
94       @admin.create_class(domain, "klassy", 1)
95     end
96     assert_raises(MogileFS::Backend::ClassExistsError) do
97       @admin.create_class(domain, "klassy", 1)
98     end
100     assert_nothing_raised do
101       @admin.update_class(domain, "klassy",
102                           :mindevcount => 1, :replpolicy => "MultipleHosts(1)")
103     end
105     tmp = nil
106     yield_for_monitor_update do
107       tmp = @admin.get_domains[domain]["klassy"]
108       break if tmp && tmp["replpolicy"] == "MultipleHosts(1)"
109     end
110     assert tmp, "domain did not show up"
111     assert_equal 1, tmp["mindevcount"]
112     assert_equal "MultipleHosts(1)", tmp["replpolicy"]
113     assert_nothing_raised { @admin.update_class(domain, "klassy", 2) }
114     ensure
115       @admin.delete_class(domain, "klassy") rescue nil
116   end
118   def add_host_device_domain
119     assert_equal [], @admin.get_hosts
120     args = { :ip => @test_host, :port => @mogstored_http_port }
121     args[:status] = "alive"
122     @admin.create_host("me", args)
123     assert File.directory?("#@docroot/dev1")
124     assert File.directory?("#@docroot/dev2")
125     yield_for_monitor_update { @admin.get_hosts.empty? or break }
127     me = @admin.get_hosts.find { |x| x["hostname"] == "me" }
128     assert_instance_of Hash, me, me.inspect
129     assert_kind_of Integer, me["hostid"], me
130     assert_equal true, @admin.create_device(me["hostid"], 1)
131     yield_for_monitor_update { @admin.get_devices.empty? or break }
132     wait_for_usage_file "dev1"
133     assert_equal true, @admin.create_device("me", 2)
134     wait_for_usage_file "dev2"
136     # MogileFS::Server 2.60+ shows reject_bad_md5 monitor status
137     dev = @admin.get_devices[0]
138     if dev.include?("reject_bad_md5")
139       assert [true, false].include?(dev["reject_bad_md5"])
140     end
142     out = err = nil
143     tries = 0
144     begin
145       out.close! if out
146       err.close! if err
147       status, out, err = mogadm("check")
148       assert status.success?, status.inspect
149       if (tries += 1) > 100
150         warn err.read
151         puts out.read
152         raise "mogadm failed"
153       end
154       sleep 0.1
155     end until out.read =~ /write?able/
157     domain = "rbmogtest.#$$"
158     @admin.create_domain(domain)
159     yield_for_monitor_update { @admin.get_domains.include?(domain) and break }
160     @domain = domain
161   end
163   def test_device_file_add
164     add_host_device_domain
165     client = MogileFS::MogileFS.new :hosts => @hosts, :domain => @domain
166     r, w = IO.pipe
167     thr = Thread.new do
168       (0..9).each do |i|
169         sleep 0.05
170         w.write("#{i}\n")
171       end
172       w.close
173       :ok
174     end
175     assert_equal 20, client.store_file("pipe", nil, r)
176     assert_equal :ok, thr.value
177     r.close
178     assert_equal "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n", client.get_file_data("pipe")
179   end
181   def teardown_mogilefs
182     if @mogstored_pid
183       pid = File.read(@mogstored_pid.path).to_i
184       Process.kill(:TERM, pid) if pid > 0
185     end
186     if @mogilefsd_pid
187       s = TCPSocket.new(@test_host, @tracker_port)
188       s.write "!shutdown\r\n"
189       s.close
190     end
191     FileUtils.rmtree(@docroot)
192   end
194   def wait_for_usage_file(device)
195     uri = URI("http://#@test_host:#@mogstored_http_port/#{device}/usage")
196     res = nil
197     100.times do
198       res = Net::HTTP.get_response(uri)
199       if Net::HTTPOK === res
200         puts res.body if $DEBUG
201         return
202       end
203       puts res.inspect if $DEBUG
204       sleep 0.1
205     end
206     raise "#{uri} failed to appear: #{res.inspect}"
207   end
209   def setup_mogstored
210     @docroot = Dir.mktmpdir(["mogfresh", "docroot"])
211     Dir.mkdir("#@docroot/dev1")
212     Dir.mkdir("#@docroot/dev2")
213     @mogstored_mgmt = TCPServer.new(@test_host, 0)
214     @mogstored_http = TCPServer.new(@test_host, 0)
215     @mogstored_mgmt_port = @mogstored_mgmt.addr[1]
216     @mogstored_http_port = @mogstored_http.addr[1]
217     @mogstored_conf = Tempfile.new(["mogstored", "conf"])
218     @mogstored_pid = Tempfile.new(["mogstored", "pid"])
219     @mogstored_conf.write <<EOF
220 pidfile = #{@mogstored_pid.path}
221 maxconns = 1000
222 httplisten = #@test_host:#{@mogstored_http_port}
223 mgmtlisten = #@test_host:#{@mogstored_mgmt_port}
224 docroot = #@docroot
226     @mogstored_conf.flush
227     @mogstored_mgmt.close
228     @mogstored_http.close
230     x!("mogstored", "--daemon", "--config=#{@mogstored_conf.path}")
231     wait_for_port @mogstored_mgmt_port
232     wait_for_port @mogstored_http_port
233   end