1 # -*- encoding: binary -*-
2 require './test/rack_read_write.rb'
3 require 'tokyocabinet' # FIXME: emits warning with 1.29 gem
7 class Test_TC_HDB < Test::Unit::TestCase
8 attr_reader :tmp, :o, :uri
9 include TestRackReadWrite
12 tmp = Tempfile.new('tchdb')
13 @path_pattern = tmp.path + ".%01x.tch"
16 @app_opts = { :path_pattern => @path_pattern, :uri => @uri }
20 Dir[@path_pattern.sub!(/%\d*x/, '*')].each { |x| File.unlink(x) }
24 Metropolis.new(@app_opts)
27 def test_create_put_get_delete
29 r = o.put('hello', { 'rack.input' => StringIO.new('world') })
30 assert_equal 201, r[0].to_i
31 assert_equal 'text/plain', r[1]['Content-Type']
32 assert_equal '8', r[1]['Content-Length']
33 assert_equal "Created\n", r[2].join('')
35 r = o.put('hellox', { 'rack.input' => StringIO.new('worldx') })
36 assert_equal 201, r[0].to_i
37 assert_equal 'text/plain', r[1]['Content-Type']
38 assert_equal '8', r[1]['Content-Length']
39 assert_equal "Created\n", r[2].join('')
41 r = o.get('hello', {})
42 assert_equal 200, r[0].to_i
43 assert_equal 'application/octet-stream', r[1]['Content-Type']
44 assert_equal '5', r[1]['Content-Length']
45 assert_equal %w(world), r[2]
47 r = o.head('hello', {})
48 assert_equal 200, r[0].to_i
49 assert_equal 'application/octet-stream', r[1]['Content-Type']
50 assert_equal '5', r[1]['Content-Length']
53 r = o.get('hellox', {})
54 assert_equal 200, r[0].to_i
55 assert_equal 'application/octet-stream', r[1]['Content-Type']
56 assert_equal '6', r[1]['Content-Length']
57 assert_equal %w(worldx), r[2]
59 r = o.delete('hellox')
60 assert_equal 200, r[0].to_i
61 assert_equal 'text/plain', r[1]['Content-Type']
62 assert_equal '3', r[1]['Content-Length']
63 assert_equal "OK\n", r[2].join('')
65 r = o.delete('hellox')
66 assert_equal 404, r[0].to_i
67 assert_equal 'text/plain', r[1]['Content-Type']
68 assert_equal '10', r[1]['Content-Length']
69 assert_equal "Not Found\n", r[2].join('')
71 r = o.get('hellox', {})
72 assert_equal 404, r[0].to_i
73 assert_equal 'text/plain', r[1]['Content-Type']
74 assert_equal '10', r[1]['Content-Length']
75 assert_equal "Not Found\n", r[2].join('')
77 r = o.head('hellox', {})
78 assert_equal 404, r[0].to_i
79 assert_equal 'text/plain', r[1]['Content-Type']
80 assert_equal '10', r[1]['Content-Length']
81 assert_equal "", r[2].join('')
87 "rack.input" => StringIO.new("hello"),
88 "HTTP_X_TT_PDMODE" => "1"
90 assert_equal 201, o.put("x", env)[0]
91 env["rack.input"] = StringIO.new("wrong")
92 assert_equal 409, o.put("x", env)[0]
93 assert_equal "hello", o.get("x", {})[2].join('')
99 "rack.input" => StringIO.new("hello"),
100 "HTTP_X_TT_PDMODE" => "2"
102 assert_equal 201, o.put("x", env)[0]
103 env["rack.input"] = StringIO.new("MOAR")
104 assert_equal 201, o.put("x", env)[0]
105 assert_equal "helloMOAR", o.get("x", {})[2].join('')
111 str = "." * (1024 * 1024)
115 sio = StringIO.new(str)
116 env = { "rack.input" => sio }
124 res = Process.waitall
125 assert_equal nr, res.size
126 res.each { |(pid, status)| assert status.success? }
127 end if ENV["TEST_EXPENSIVE"]
132 wr.put(key, { "rack.input" => StringIO.new("OK") })
133 o = Metropolis.new(@app_opts.merge(:readonly => true))
134 %w(PUT DELETE).each do |rm|
136 "rack.input" => StringIO.new("FAIL"),
137 "REQUEST_METHOD" => rm,
138 "PATH_INFO" => "/#{key}"
140 assert_equal 403, o.call(env)[0]
143 "REQUEST_METHOD" => "GET",
144 "PATH_INFO" => "/#{key}",
146 assert_equal 200, o.call(env)[0]
147 assert_equal '2', o.call(env)[1]["Content-Length"]
148 assert_equal 'application/octet-stream', o.call(env)[1]["Content-Type"]
149 assert_equal "OK", o.call(env)[2].join('')
151 env["REQUEST_METHOD"] = "HEAD"
152 assert_equal 200, o.call(env)[0]
153 assert_equal '2', o.call(env)[1]["Content-Length"]
154 assert_equal 'application/octet-stream', o.call(env)[1]["Content-Type"]
155 assert_equal "", o.call(env)[2].join('')
158 def test_create_toplevel
160 nr_bytes = 1024 * 1024 * 20
161 data = "0" * nr_bytes
163 assert_nothing_raised { obj = Metropolis.new(@app_opts) }
165 query = "large=true&apow=3&bnum=65536&compress=deflate"
166 assert_nothing_raised {
167 obj = Metropolis.new(@app_opts.merge(:uri => "#{uri}?#{query}"))
169 optimize_args = obj.instance_variable_get(:@optimize)
170 flags = TokyoCabinet::HDB::TLARGE | TokyoCabinet::HDB::TDEFLATE
171 assert_equal flags, optimize_args[3]
172 assert_equal 65536, optimize_args[0]
173 assert_nil optimize_args[2]
174 assert_equal 3, optimize_args[1]
175 assert_nothing_raised { obj.get(k, {}) }
176 assert_nothing_raised { obj.put(k,{'rack.input' => StringIO.new(data)}) }
178 opts = @app_opts.merge(:uri => "#{uri}?#{query}", :readonly => true)
179 obj = Metropolis.new(opts)
180 assert_equal data, obj.get(k, {})[2].join('')
183 opts = @app_opts.merge(:uri => uri, :readonly => true)
184 obj = Metropolis.new(opts)
185 assert_equal data, obj.get(k, {})[2].join('')
187 sum = obj.instance_eval {
188 @dbv.inject(0) { |size, (hdb,path)| size += File.stat(path).size }
190 assert sum <= nr_bytes, "#{sum} > #{nr_bytes}"
195 opts = @app_opts.merge(:uri => uri, :exclusive => true)
196 @app = Metropolis.new(opts)
197 assert_equal(app.method(:reader), app.method(:writer))
202 opts = @app_opts.merge(:uri => "#{uri}?rdlock=false")
203 @app = Metropolis.new(opts)
204 nolck = ::TokyoCabinet::HDB::ONOLCK
205 flags = @app.instance_variable_get(:@rd_flags)
206 assert((flags & nolck) == nolck)
207 flags = @app.instance_variable_get(:@wr_flags)
208 assert((flags & nolck) == 0)
213 @app = Metropolis.new(@app_opts.merge(:uri => "#{uri}?wrlock=false"))
214 nolck = ::TokyoCabinet::HDB::ONOLCK
215 flags = @app.instance_variable_get(:@wr_flags)
216 assert((flags & nolck) == nolck)
217 flags = @app.instance_variable_get(:@rd_flags)
218 assert((flags & nolck) == 0)