fluent-plugin-hoop 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/.gitignore +31 -0
- data/.gitmodules +3 -0
- data/AUTHORS +1 -0
- data/Gemfile +16 -0
- data/LICENSE.txt +13 -0
- data/README.rdoc +79 -0
- data/Rakefile +64 -0
- data/VERSION +1 -0
- data/fluent-plugin-hoop.gemspec +75 -0
- data/lib/fluent/plugin/out_hoop.rb +339 -0
- data/test/helper.rb +53 -0
- data/test/plugin/test_out_hoop.rb +441 -0
- data/test/plugin/test_out_hoop_realserver.rb +145 -0
- data/test/plugin/test_out_hoop_reconnect.rb +185 -0
- metadata +156 -0
data/test/helper.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'test/unit'
|
11
|
+
require 'shoulda'
|
12
|
+
|
13
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
14
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
15
|
+
require 'fluent/test'
|
16
|
+
|
17
|
+
if ENV['FLUENT_TEST_DEBUG'] == 'TRUE'
|
18
|
+
nulllogger = Object.new
|
19
|
+
nulllogger.instance_eval {|obj|
|
20
|
+
def method_missing(method, *args)
|
21
|
+
# pass
|
22
|
+
end
|
23
|
+
}
|
24
|
+
$log = nulllogger
|
25
|
+
end
|
26
|
+
|
27
|
+
require 'fluent/plugin/out_hoop'
|
28
|
+
|
29
|
+
class Test::Unit::TestCase
|
30
|
+
end
|
31
|
+
|
32
|
+
require 'webrick'
|
33
|
+
|
34
|
+
# to handle PUT/DELETE ...
|
35
|
+
module WEBrick::HTTPServlet
|
36
|
+
class ProcHandler < AbstractServlet
|
37
|
+
alias do_PUT do_GET
|
38
|
+
alias do_DELETE do_GET
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def get_code(server, port, path, headers)
|
43
|
+
require 'net/http'
|
44
|
+
Net::HTTP.start(server, port){|http|
|
45
|
+
http.get(path, headers).code
|
46
|
+
}
|
47
|
+
end
|
48
|
+
def get_content(server, port, path, headers)
|
49
|
+
require 'net/http'
|
50
|
+
Net::HTTP.start(server, port){|http|
|
51
|
+
http.get(path, headers).body
|
52
|
+
}
|
53
|
+
end
|
@@ -0,0 +1,441 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class HoopOutputTest < Test::Unit::TestCase
|
4
|
+
# setup/teardown and tests of dummy hoop server defined at the end of this class...
|
5
|
+
|
6
|
+
CONFIG = %[
|
7
|
+
hoop_server localhost:14000
|
8
|
+
path /logs/from/fluentd/foo-%Y%m%d
|
9
|
+
username hoopuser
|
10
|
+
]
|
11
|
+
|
12
|
+
def create_driver(conf=CONFIG, tag='test')
|
13
|
+
Fluent::Test::TimeSlicedOutputTestDriver.new(Fluent::HoopOutput, tag).configure(conf)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_configure
|
17
|
+
assert_raise(Fluent::ConfigError) {
|
18
|
+
d = create_driver %[
|
19
|
+
]
|
20
|
+
}
|
21
|
+
assert_raise(Fluent::ConfigError) {
|
22
|
+
d = create_driver %[
|
23
|
+
path /logs/from/fluentd/foo-%Y%m%d%H
|
24
|
+
username hoopuser
|
25
|
+
]
|
26
|
+
}
|
27
|
+
assert_raise(Fluent::ConfigError) {
|
28
|
+
d = create_driver %[
|
29
|
+
hoop_server hoop.master.local:14000
|
30
|
+
username hoopuser
|
31
|
+
]
|
32
|
+
}
|
33
|
+
assert_raise(Fluent::ConfigError) {
|
34
|
+
d = create_driver %[
|
35
|
+
hoop_server hoop.master.local:14000
|
36
|
+
path /logs/from/fluentd/foo-%Y%m%d%H
|
37
|
+
]
|
38
|
+
}
|
39
|
+
assert_raise(Fluent::ConfigError) {
|
40
|
+
d = create_driver %[
|
41
|
+
hoop_server hoop.master.local
|
42
|
+
path /logs/from/fluentd/foo-%Y%m%d%H
|
43
|
+
username hoopuser
|
44
|
+
]
|
45
|
+
}
|
46
|
+
assert_raise(Fluent::ConfigError) {
|
47
|
+
d = create_driver %[
|
48
|
+
hoop_server hoop.master.local:xxx
|
49
|
+
path /logs/from/fluentd/foo-%Y%m%d%H
|
50
|
+
username hoopuser
|
51
|
+
]
|
52
|
+
}
|
53
|
+
assert_raise(Fluent::ConfigError) {
|
54
|
+
d = create_driver %[
|
55
|
+
hoop_server hoop.master.local:xxx
|
56
|
+
path logs/from/fluentd/foo-%Y%m%d%H
|
57
|
+
username hoopuser
|
58
|
+
]
|
59
|
+
}
|
60
|
+
assert_raise(Fluent::ConfigError) {
|
61
|
+
d = create_driver %[
|
62
|
+
hoop_server hoop.master.local:14000
|
63
|
+
path /logs/from/fluentd/access.log.%Y%m%d
|
64
|
+
output_include_tag true
|
65
|
+
remove_prefix testing
|
66
|
+
]
|
67
|
+
}
|
68
|
+
|
69
|
+
# config_param :path, :string # /path/pattern/to/hdfs/file can use %Y %m %d %H %M %S and %T(tag, not-supported-yet)
|
70
|
+
|
71
|
+
d = create_driver(CONFIG)
|
72
|
+
|
73
|
+
assert_equal '%Y%m%d', d.instance.time_slice_format
|
74
|
+
|
75
|
+
assert_equal 'localhost:14000', d.instance.hoop_server
|
76
|
+
assert_equal '/logs/from/fluentd/foo-%Y%m%d', d.instance.path
|
77
|
+
assert_equal 'hoopuser', d.instance.username
|
78
|
+
|
79
|
+
assert_equal true, d.instance.output_include_time
|
80
|
+
assert_equal true, d.instance.output_include_tag
|
81
|
+
assert_equal 'json', d.instance.output_data_type
|
82
|
+
assert_equal true, d.instance.add_newline
|
83
|
+
assert_equal "\t", d.instance.field_separator
|
84
|
+
|
85
|
+
assert_nil d.instance.remove_prefix
|
86
|
+
|
87
|
+
d = create_driver(CONFIG + %[
|
88
|
+
add_newline false
|
89
|
+
remove_prefix testing
|
90
|
+
default_tag unknown
|
91
|
+
], 'testing.error')
|
92
|
+
assert_equal 'testing.error', d.tag
|
93
|
+
|
94
|
+
assert_equal '%Y%m%d', d.instance.time_slice_format
|
95
|
+
|
96
|
+
assert_equal 'localhost:14000', d.instance.hoop_server
|
97
|
+
assert_equal '/logs/from/fluentd/foo-%Y%m%d', d.instance.path
|
98
|
+
assert_equal 'hoopuser', d.instance.username
|
99
|
+
|
100
|
+
assert_equal true, d.instance.output_include_time
|
101
|
+
assert_equal true, d.instance.output_include_tag
|
102
|
+
assert_equal 'json', d.instance.output_data_type
|
103
|
+
assert_equal false, d.instance.add_newline
|
104
|
+
assert_equal "\t", d.instance.field_separator
|
105
|
+
|
106
|
+
assert_equal 'testing', d.instance.remove_prefix
|
107
|
+
assert_equal 'unknown', d.instance.default_tag
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_configure_path_and_slice_format
|
111
|
+
d = create_driver(CONFIG)
|
112
|
+
assert_equal '%Y%m%d', d.instance.time_slice_format
|
113
|
+
assert_equal '/logs/from/fluentd/foo-%Y%m%d', d.instance.path
|
114
|
+
assert_equal '/logs/from/fluentd/foo-20111125', d.instance.path_format('20111125')
|
115
|
+
|
116
|
+
d = create_driver CONFIG + %[
|
117
|
+
path /logs/from/fluentd/foo-%Y%m
|
118
|
+
]
|
119
|
+
assert_equal '%Y%m%d', d.instance.time_slice_format
|
120
|
+
assert_equal '/logs/from/fluentd/foo-%Y%m', d.instance.path
|
121
|
+
assert_equal '/logs/from/fluentd/foo-201111', d.instance.path_format('20111125')
|
122
|
+
|
123
|
+
d = create_driver CONFIG + %[
|
124
|
+
path /logs/from/fluentd/foo-%Y%m%d%H
|
125
|
+
]
|
126
|
+
assert_equal '%Y%m%d%H', d.instance.time_slice_format
|
127
|
+
assert_equal '/logs/from/fluentd/foo-%Y%m%d%H', d.instance.path
|
128
|
+
assert_equal '/logs/from/fluentd/foo-2011112508', d.instance.path_format('2011112508')
|
129
|
+
|
130
|
+
d = create_driver CONFIG + %[
|
131
|
+
path /logs/from/fluentd/foo-%Y%m%d%H%M
|
132
|
+
]
|
133
|
+
assert_equal '%Y%m%d%H%M', d.instance.time_slice_format
|
134
|
+
assert_equal '/logs/from/fluentd/foo-%Y%m%d%H%M', d.instance.path
|
135
|
+
assert_equal '/logs/from/fluentd/foo-201111250811', d.instance.path_format('201111250811')
|
136
|
+
|
137
|
+
d = create_driver CONFIG + %[
|
138
|
+
path /logs/from/fluentd/foo-%Y%m%d%H%M%S
|
139
|
+
]
|
140
|
+
assert_equal '%Y%m%d%H%M%S', d.instance.time_slice_format
|
141
|
+
assert_equal '/logs/from/fluentd/foo-%Y%m%d%H%M%S', d.instance.path
|
142
|
+
assert_equal '/logs/from/fluentd/foo-20111125081159', d.instance.path_format('20111125081159')
|
143
|
+
|
144
|
+
d = create_driver CONFIG + %[
|
145
|
+
path /logs/from/fluentd/foo-%m%d%H
|
146
|
+
]
|
147
|
+
assert_equal '%Y%m%d%H', d.instance.time_slice_format
|
148
|
+
assert_equal '/logs/from/fluentd/foo-%m%d%H', d.instance.path
|
149
|
+
assert_equal '/logs/from/fluentd/foo-112508', d.instance.path_format('2011112508')
|
150
|
+
|
151
|
+
d = create_driver CONFIG + %[
|
152
|
+
path /logs/from/fluentd/foo-%M%S.log
|
153
|
+
]
|
154
|
+
assert_equal '%Y%m%d%H%M%S', d.instance.time_slice_format
|
155
|
+
assert_equal '/logs/from/fluentd/foo-%M%S.log', d.instance.path
|
156
|
+
assert_equal '/logs/from/fluentd/foo-1159.log', d.instance.path_format('20111125081159')
|
157
|
+
|
158
|
+
d = create_driver CONFIG + %[
|
159
|
+
path /logs/from/fluentd/%Y%m%d/%H/foo-%M-%S.log
|
160
|
+
]
|
161
|
+
assert_equal '%Y%m%d%H%M%S', d.instance.time_slice_format
|
162
|
+
assert_equal '/logs/from/fluentd/%Y%m%d/%H/foo-%M-%S.log', d.instance.path
|
163
|
+
assert_equal '/logs/from/fluentd/20111125/08/foo-11-59.log', d.instance.path_format('20111125081159')
|
164
|
+
end
|
165
|
+
|
166
|
+
def test_format
|
167
|
+
d = create_driver
|
168
|
+
time = Time.parse("2011-11-25 13:14:15 UTC").to_i
|
169
|
+
d.emit({"a"=>1}, time)
|
170
|
+
d.emit({"a"=>2}, time)
|
171
|
+
d.expect_format %[2011-11-25T13:14:15Z\ttest\t{"a":1}\n]
|
172
|
+
d.expect_format %[2011-11-25T13:14:15Z\ttest\t{"a":2}\n]
|
173
|
+
d.run
|
174
|
+
|
175
|
+
d = create_driver(CONFIG + %[
|
176
|
+
remove_prefix testing
|
177
|
+
default_tag unknown
|
178
|
+
], 'testing.log')
|
179
|
+
assert_equal 'testing.log', d.tag
|
180
|
+
time = Time.parse("2011-11-25 13:14:15 UTC").to_i
|
181
|
+
d.emit({"a"=>1}, time)
|
182
|
+
d.emit({"a"=>2}, time)
|
183
|
+
d.expect_format %[2011-11-25T13:14:15Z\tlog\t{"a":1}\n]
|
184
|
+
d.expect_format %[2011-11-25T13:14:15Z\tlog\t{"a":2}\n]
|
185
|
+
d.run
|
186
|
+
|
187
|
+
d = create_driver(CONFIG + %[
|
188
|
+
remove_prefix testing
|
189
|
+
default_tag unknown
|
190
|
+
], 'extra.testing.log')
|
191
|
+
time = Time.parse("2011-11-25 13:14:15 UTC").to_i
|
192
|
+
d.emit({"a"=>1}, time)
|
193
|
+
d.emit({"a"=>2}, time)
|
194
|
+
d.expect_format %[2011-11-25T13:14:15Z\textra.testing.log\t{"a":1}\n]
|
195
|
+
d.expect_format %[2011-11-25T13:14:15Z\textra.testing.log\t{"a":2}\n]
|
196
|
+
d.run
|
197
|
+
|
198
|
+
d = create_driver(CONFIG + %[
|
199
|
+
remove_prefix testing
|
200
|
+
default_tag unknown
|
201
|
+
], 'testing')
|
202
|
+
time = Time.parse("2011-11-25 13:14:15 UTC").to_i
|
203
|
+
d.emit({"a"=>1}, time)
|
204
|
+
d.emit({"a"=>2}, time)
|
205
|
+
d.expect_format %[2011-11-25T13:14:15Z\tunknown\t{"a":1}\n]
|
206
|
+
d.expect_format %[2011-11-25T13:14:15Z\tunknown\t{"a":2}\n]
|
207
|
+
d.run
|
208
|
+
|
209
|
+
d = create_driver CONFIG + %[
|
210
|
+
output_include_tag false
|
211
|
+
]
|
212
|
+
time = Time.parse("2011-11-25 13:14:15 UTC").to_i
|
213
|
+
d.emit({"a"=>1}, time)
|
214
|
+
d.emit({"a"=>2}, time)
|
215
|
+
d.expect_format %[2011-11-25T13:14:15Z\t{"a":1}\n]
|
216
|
+
d.expect_format %[2011-11-25T13:14:15Z\t{"a":2}\n]
|
217
|
+
d.run
|
218
|
+
|
219
|
+
d = create_driver CONFIG + %[
|
220
|
+
output_include_time false
|
221
|
+
]
|
222
|
+
time = Time.parse("2011-11-25 13:14:15 UTC").to_i
|
223
|
+
d.emit({"a"=>1}, time)
|
224
|
+
d.emit({"a"=>2}, time)
|
225
|
+
d.expect_format %[test\t{"a":1}\n]
|
226
|
+
d.expect_format %[test\t{"a":2}\n]
|
227
|
+
d.run
|
228
|
+
|
229
|
+
d = create_driver CONFIG + %[
|
230
|
+
output_include_time false
|
231
|
+
output_include_tag false
|
232
|
+
]
|
233
|
+
time = Time.parse("2011-11-25 13:14:15 UTC").to_i
|
234
|
+
d.emit({"a"=>1}, time)
|
235
|
+
d.emit({"a"=>2}, time)
|
236
|
+
d.expect_format %[{"a":1}\n]
|
237
|
+
d.expect_format %[{"a":2}\n]
|
238
|
+
d.run
|
239
|
+
|
240
|
+
d = create_driver CONFIG + %[
|
241
|
+
output_include_time false
|
242
|
+
output_include_tag false
|
243
|
+
output_data_type attr:a
|
244
|
+
add_newline true # default
|
245
|
+
]
|
246
|
+
time = Time.parse("2011-11-25 13:14:15 UTC").to_i
|
247
|
+
d.emit({"a"=>1}, time)
|
248
|
+
d.emit({"a"=>2}, time)
|
249
|
+
d.expect_format %[1\n]
|
250
|
+
d.expect_format %[2\n]
|
251
|
+
d.run
|
252
|
+
|
253
|
+
d = create_driver CONFIG + %[
|
254
|
+
output_include_time false
|
255
|
+
output_include_tag false
|
256
|
+
output_data_type attr:a
|
257
|
+
add_newline false
|
258
|
+
]
|
259
|
+
time = Time.parse("2011-11-25 13:14:15 UTC").to_i
|
260
|
+
d.emit({"a"=>1}, time)
|
261
|
+
d.emit({"a"=>2}, time)
|
262
|
+
d.expect_format %[1]
|
263
|
+
d.expect_format %[2]
|
264
|
+
d.run
|
265
|
+
|
266
|
+
d = create_driver CONFIG + %[
|
267
|
+
output_include_time false
|
268
|
+
output_include_tag false
|
269
|
+
output_data_type attr:a,b,c
|
270
|
+
add_newline true
|
271
|
+
]
|
272
|
+
time = Time.parse("2011-11-25 13:14:15 UTC").to_i
|
273
|
+
d.emit({"a"=>1}, time)
|
274
|
+
d.emit({"a"=>2,"c"=>6,"b"=>4}, time)
|
275
|
+
d.expect_format %[1\tNULL\tNULL\n]
|
276
|
+
d.expect_format %[2\t4\t6\n]
|
277
|
+
d.run
|
278
|
+
|
279
|
+
d = create_driver CONFIG + %[
|
280
|
+
output_include_time false
|
281
|
+
output_include_tag false
|
282
|
+
output_data_type attr:message
|
283
|
+
add_newline false
|
284
|
+
]
|
285
|
+
time = Time.parse("2011-11-25 13:14:15 UTC").to_i
|
286
|
+
d.emit({"tag"=>"from.scribe", "message"=>'127.0.0.1 - tagomoris [25/Nov/2011:20:19:04 +0900] "GET http://example.com/api/ HTTP/1.1" 200 39 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.874.121 Safari/535.2" "-" 71383"' + "\n"}, time)
|
287
|
+
d.expect_format '127.0.0.1 - tagomoris [25/Nov/2011:20:19:04 +0900] "GET http://example.com/api/ HTTP/1.1" 200 39 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.874.121 Safari/535.2" "-" 71383"' + "\n"
|
288
|
+
d.run
|
289
|
+
end
|
290
|
+
|
291
|
+
def test_write
|
292
|
+
d = create_driver CONFIG + %[
|
293
|
+
utc
|
294
|
+
]
|
295
|
+
|
296
|
+
assert_equal '404', get_code('localhost', 14000, '/logs/from/fluentd/foo-20111124', {'Cookie' => VALID_COOKIE_STRING})
|
297
|
+
|
298
|
+
time = Time.parse("2011-11-24 00:14:15 UTC").to_i
|
299
|
+
d.emit({"a"=>1}, time)
|
300
|
+
d.emit({"a"=>2}, time)
|
301
|
+
paths = d.run
|
302
|
+
assert_equal ['/logs/from/fluentd/foo-20111124'], paths
|
303
|
+
assert_equal %[2011-11-24T00:14:15Z\ttest\t{"a":1}\n2011-11-24T00:14:15Z\ttest\t{"a":2}\n], get_content('localhost', 14000, paths.first, {'Cookie' => VALID_COOKIE_STRING})
|
304
|
+
end
|
305
|
+
|
306
|
+
VALID_COOKIE_VALUE = 'u=hoopuser&p=hoopuser&t=simple&e=1322203001386&s=SErpv88rOAVEItSOIoCtIV/DSpE='
|
307
|
+
VALID_COOKIE_STRING = 'alfredo.auth="u=hoopuser&p=hoopuser&t=simple&e=1322203001386&s=SErpv88rOAVEItSOIoCtIV/DSpE="'
|
308
|
+
RES_COOKIE_AUTH_FAILURE = WEBrick::Cookie.parse_set_cookie('alfredo.auth=""; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/')
|
309
|
+
RES_COOKIE_AUTH_SUCCESS = WEBrick::Cookie.parse_set_cookie(VALID_COOKIE_STRING + '; Version=1; Path=/')
|
310
|
+
RES_BODY_STATUS_ROOT = '{"path":"http:\/\/localhost:14000\/","isDir":true,"len":0,"owner":"hoopuser","group":"supergroup","permission":"-rwxr-xr-x","accessTime":0,"modificationTime":1320055230010,"blockSize":0,"replication":0}'
|
311
|
+
RES_FORMAT_ALREADY_EXISTS = "{\"statusCode\":500,\"reason\":\"Internal Server Error\",\"message\":\"java.io.IOException: failed to create file %s on client 127.0.0.1 either because the filename is invalid or the file exists\",\"exception\":\"org.apache.hadoop.ipc.RemoteException\"}"
|
312
|
+
RES_FORMAT_NOT_FOUND = "{\"statusCode\":404,\"reason\":\"Not Found\",\"message\":\"java.io.FileNotFoundException: failed to append to non-existent file %s on client 127.0.0.1\",\"exception\":\"java.io.FileNotFoundException\"}"
|
313
|
+
RES_FORMAT_NOT_FOUND_GET = "{\"statusCode\":404,\"reason\":\"Not Found\",\"message\":\"File does not exist: %s\",\"exception\":\"java.io.FileNotFoundException\"}"
|
314
|
+
|
315
|
+
CONTENT_TYPE_JSON = 'application/json'
|
316
|
+
|
317
|
+
def setup
|
318
|
+
Fluent::Test.setup
|
319
|
+
@dummy_server_thread = Thread.new do
|
320
|
+
srv = if ENV['FLUENT_TEST_DEBUG']
|
321
|
+
logger = WEBrick::Log.new('/dev/null', WEBrick::BasicLog::DEBUG)
|
322
|
+
WEBrick::HTTPServer.new({:BindAddress => '127.0.0.1', :Port => 14000, :Logger => logger, :AccessLog => []})
|
323
|
+
else
|
324
|
+
WEBrick::HTTPServer.new({:BindAddress => '127.0.0.1', :Port => 14000})
|
325
|
+
end
|
326
|
+
@fsdata = {}
|
327
|
+
begin
|
328
|
+
srv.mount_proc('/'){|req,res|
|
329
|
+
# status only...
|
330
|
+
if req.query['user.name'] or req.cookies.index{|item| item.name == 'alfredo.auth' and item.value}
|
331
|
+
res.status = 200
|
332
|
+
res.content_type = CONTENT_TYPE_JSON
|
333
|
+
res.cookies << RES_COOKIE_AUTH_SUCCESS
|
334
|
+
res.body = RES_BODY_STATUS_ROOT
|
335
|
+
else
|
336
|
+
res.cookies << RES_COOKIE_AUTH_FAILURE
|
337
|
+
res.status = 401
|
338
|
+
end
|
339
|
+
}
|
340
|
+
srv.mount_proc('/logs/from/fluentd') {|req, res|
|
341
|
+
if req.request_method == 'POST' or req.request_method == 'PUT' or req.request_method == 'DELETE'
|
342
|
+
# WEBrick's default handler ignores query parameter of URI without method GET
|
343
|
+
req.query.update(Hash[*(req.request_line.split(' ')[1].split('?')[1].split('&').map{|kv|kv.split('=')}.flatten)])
|
344
|
+
end
|
345
|
+
case
|
346
|
+
when (not req.query['user.name'] and req.cookies.index{|i| i.name == 'alfredo.auth' and i.value == VALID_COOKIE_VALUE} < 0)
|
347
|
+
res.cookies << RES_COOKIE_AUTH_FAILURE
|
348
|
+
res.status = 401
|
349
|
+
when (req.query['op'] == 'create' and @fsdata[req.path] and req.query['overwrite'] and req.query['overwrite'] == 'false')
|
350
|
+
res.status = 500
|
351
|
+
res.content_type = CONTENT_TYPE_JSON
|
352
|
+
res.body = sprintf RES_FORMAT_ALREADY_EXISTS, req.path
|
353
|
+
when req.query['op'] == 'create'
|
354
|
+
@fsdata[req.path] = req.body
|
355
|
+
res.status = 201
|
356
|
+
res['Location'] = 'http://localhost:14000' + req.path
|
357
|
+
res.content_type = CONTENT_TYPE_JSON
|
358
|
+
when (req.query['op'] == 'append' and @fsdata[req.path])
|
359
|
+
@fsdata[req.path] += req.body
|
360
|
+
res.status = 200
|
361
|
+
res['Location'] = 'http://localhost:14000' + req.path
|
362
|
+
res.content_type = CONTENT_TYPE_JSON
|
363
|
+
when req.query['op'] == 'append'
|
364
|
+
res.status = 404
|
365
|
+
res.content_type = CONTENT_TYPE_JSON
|
366
|
+
res.body = sprintf RES_FORMAT_NOT_FOUND, req.path
|
367
|
+
when (req.request_method == 'GET' and @fsdata[req.path]) # maybe GET
|
368
|
+
res.status = 200
|
369
|
+
res.content_type = 'application/octet-stream'
|
370
|
+
res.body = @fsdata[req.path]
|
371
|
+
else
|
372
|
+
res.status = 404
|
373
|
+
res.content_type = CONTENT_TYPE_JSON
|
374
|
+
res.body = sprintf RES_FORMAT_NOT_FOUND_GET, req.path
|
375
|
+
end
|
376
|
+
}
|
377
|
+
srv.start
|
378
|
+
ensure
|
379
|
+
srv.shutdown
|
380
|
+
end
|
381
|
+
end
|
382
|
+
|
383
|
+
# to wait completion of dummy server.start()
|
384
|
+
require 'thread'
|
385
|
+
cv = ConditionVariable.new
|
386
|
+
watcher = Thread.new {
|
387
|
+
connected = false
|
388
|
+
while not connected
|
389
|
+
begin
|
390
|
+
get_content('localhost', 14000, '/', {'Cookie' => VALID_COOKIE_STRING})
|
391
|
+
connected = true
|
392
|
+
rescue Errno::ECONNREFUSED
|
393
|
+
sleep 0.1
|
394
|
+
rescue StandardError => e
|
395
|
+
p e
|
396
|
+
sleep 0.1
|
397
|
+
end
|
398
|
+
end
|
399
|
+
cv.signal
|
400
|
+
}
|
401
|
+
mutex = Mutex.new
|
402
|
+
mutex.synchronize {
|
403
|
+
cv.wait(mutex)
|
404
|
+
}
|
405
|
+
end
|
406
|
+
|
407
|
+
def test_dummy_server
|
408
|
+
d = create_driver
|
409
|
+
authheader = {'Cookie' => VALID_COOKIE_STRING}
|
410
|
+
client = Net::HTTP.start(d.instance.hoop_server.split(':')[0], d.instance.hoop_server.split(':')[1])
|
411
|
+
assert_equal '401', client.request_get('/').code
|
412
|
+
assert_equal '200', client.request_get('/?user.name=hoopuser').code
|
413
|
+
assert_equal '200', client.request_get('/', authheader).code
|
414
|
+
|
415
|
+
# /logs/from/fluentd
|
416
|
+
path1 = '/logs/from/fluentd/hoge001/moge-access-log'
|
417
|
+
path1_line1 = "1111111111111111111111111111111\n"
|
418
|
+
path1_line2 = "2222222222222222222222222222222222222222222222222\n"
|
419
|
+
assert_equal '404', client.request_put(path1 + '?op=append', path1_line1, authheader).code
|
420
|
+
assert_equal '201', client.request_post(path1 + '?op=create&overwrite=false', path1_line1, authheader).code
|
421
|
+
assert_equal path1_line1, client.request_get(path1, authheader).body
|
422
|
+
assert_equal '200', client.request_put(path1 + '?op=append', path1_line2, authheader).code
|
423
|
+
assert_equal path1_line1 + path1_line2, client.request_get(path1, authheader).body
|
424
|
+
|
425
|
+
path2 = '/logs/from/fluentd/hoge002/moge-access-log'
|
426
|
+
path2_line1 = "XXXXX___1111111111111111111111111111111\n"
|
427
|
+
path2_line2 = "YYYYY___2222222222222222222222222222222222222222222222222\n"
|
428
|
+
assert_equal '404', client.request_put(path2 + '?op=append', path2_line1, authheader).code
|
429
|
+
assert_equal '201', client.request_post(path2 + '?op=create&overwrite=false', path2_line1, authheader).code
|
430
|
+
assert_equal '500', client.request_post(path2 + '?op=create&overwrite=false', path2_line1, authheader).code
|
431
|
+
assert_equal path2_line1, client.request_get(path2, authheader).body
|
432
|
+
assert_equal '200', client.request_put(path2 + '?op=append', path2_line2, authheader).code
|
433
|
+
assert_equal path2_line1 + path2_line2, client.request_get(path2, authheader).body
|
434
|
+
assert_equal path2_line1 + path2_line2, get_content('localhost', 14000, path2, authheader)
|
435
|
+
end
|
436
|
+
|
437
|
+
def teardown
|
438
|
+
@dummy_server_thread.kill
|
439
|
+
@dummy_server_thread.join
|
440
|
+
end
|
441
|
+
end
|