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