client: small speedup for list_keys_verbose
[ruby-mogilefs-client.git] / test / setup.rb
blob8fda7f11a0c9ef2e051dd3a30ce300639e6f66d3
1 # -*- encoding: binary -*-
2 STDIN.sync = STDOUT.sync = STDERR.sync = true
3 Thread.abort_on_exception = true
4 require 'test/unit'
5 require 'tempfile'
6 require 'fileutils'
7 require 'tmpdir'
8 require 'stringio'
10 trap('CHLD') { Process.waitpid(-1, Process::WNOHANG) rescue nil }
12 $TESTING = true
14 require 'mogilefs'
16 class FakeBackend
18   attr_reader :lasterr, :lasterrstr
20   def initialize
21     @responses = Hash.new { |h,k| h[k] = [] }
22     @lasterr = nil
23     @lasterrstr = nil
24   end
26   def error(err_snake)
27     err_camel = err_snake.gsub(/(?:^|_)([a-z])/) { $1.upcase } << 'Error'
28     unless MogileFS::Backend.const_defined?(err_camel)
29       MogileFS::Backend.class_eval("class #{err_camel} < MogileFS::Error; end")
30     end
31     MogileFS::Backend.const_get(err_camel)
32   end
34   def method_missing(meth, *args)
35     meth = meth.to_s
36     if meth =~ /(.*)=$/ then
37       @responses[$1] << args.first
38     else
39       response = @responses[meth].shift
40       case response
41       when Array then
42         @lasterr = response.first
43         @lasterrstr = response.last
44         raise error(@lasterr), @lasterrstr
45         return nil
46       end
47       return response
48     end
49   end
51 end
53 class MogileFS::Client
54   attr_writer :readonly
55 end
57 require 'socket'
58 class TempServer
59   attr_reader :port, :pid
61   def self.destroy_all!
62     ObjectSpace.each_object(TempServer) { |t| t.destroy! }
63   end
65   at_exit { TempServer.destroy_all! }
67   def initialize(server_proc, port = nil)
68     @pid = @sock = nil
69     @port = port
70     retries = 10
71     begin
72       @port ||= 1024 + rand(32768 - 1024)
73       @sock = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
74       @sock.bind(Socket.pack_sockaddr_in(@port.to_i, '127.0.0.1'))
75       @sock.listen(5)
76     rescue Errno::EADDRINUSE, Errno::EACCES => err
77       @sock.close rescue nil
78       @port = nil
79       retry if port.nil? && (retries -= 1) > 0
80       warn "retries failed: #{retries} port=#{port.inspect}"
81       raise err
82     end
83     @pid = fork { server_proc.call(@sock, @port) }
84     @sock.close rescue nil
85   end
87   def destroy!
88     @sock.close rescue nil
89     Process.kill('KILL', @pid) rescue nil
90   end
92 end
94 class TestMogileFS < Test::Unit::TestCase
96   undef_method :default_test if method_defined?(:default_test)
98   def setup
99     @client = @klass.new :hosts => ['kaa:6001'], :domain => 'test'
100     @backend = FakeBackend.new
101     @client.instance_variable_set '@backend', @backend
102   end
106 # for our mock results
107 class Array
108   alias_method :fetch_row, :shift
111 class FakeMysql
112   attr_reader :expect
113   TBL_DEVICES = [
114     # devid, hostip, altip, http_port, http_get_port, dev status, host status
115     [ 1, '10.0.0.1', '192.168.0.1', 7500, 7600, 'readonly', 'alive' ],
116     [ 2, '10.0.0.2', '192.168.0.2', 7500, 7600, 'alive', 'alive' ],
117     [ 3, '10.0.0.3', nil, 7500, nil, 'readonly', 'alive' ],
118     [ 4, '10.0.0.4', nil, 7500, nil, 'alive', 'alive' ],
119     [ 5, '10.0.0.5', nil, 7500, nil, 'dead', 'alive' ],
120     [ 6, '10.0.0.6', nil, 7500, nil, 'alive', 'down' ],
121   ]
122   TBL_DOMAINS = [
123     # dmid, namespace
124     [ 1, 'test' ],
125     [ 2, 'foo' ],
126   ]
128   def initialize
129     @expect = []
130   end
132   def quote(str)
133     str.to_s.gsub(/\\/, '\&\&').gsub(/'/, "''")
134   end
136   def query(sql = '')
137     case sql
138     when MogileFS::Mysql::GET_DEVICES then TBL_DEVICES
139     when MogileFS::Mysql::GET_DOMAINS then TBL_DOMAINS
140     else
141       @expect.shift
142     end
143   end