fluentd 0.14.17-x64-mingw32 → 1.3.1-x64-mingw32
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of fluentd might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.travis.yml +16 -5
- data/ADOPTERS.md +5 -0
- data/{ChangeLog → CHANGELOG.md} +495 -6
- data/CONTRIBUTING.md +5 -2
- data/GOVERNANCE.md +55 -0
- data/LICENSE +202 -0
- data/MAINTAINERS.md +7 -5
- data/README.md +17 -10
- data/bin/fluent-ca-generate +6 -0
- data/example/counter.conf +18 -0
- data/example/secondary_file.conf +3 -2
- data/fluentd.gemspec +3 -3
- data/lib/fluent/agent.rb +1 -1
- data/lib/fluent/command/binlog_reader.rb +11 -2
- data/lib/fluent/command/ca_generate.rb +181 -0
- data/lib/fluent/command/cat.rb +28 -15
- data/lib/fluent/command/debug.rb +4 -4
- data/lib/fluent/command/fluentd.rb +2 -2
- data/lib/fluent/command/plugin_config_formatter.rb +24 -2
- data/lib/fluent/command/plugin_generator.rb +26 -8
- data/lib/fluent/config/configure_proxy.rb +7 -1
- data/lib/fluent/config/dsl.rb +8 -5
- data/lib/fluent/config/element.rb +5 -0
- data/lib/fluent/config/literal_parser.rb +7 -1
- data/lib/fluent/config/types.rb +28 -2
- data/lib/fluent/config/v1_parser.rb +1 -2
- data/lib/fluent/configurable.rb +1 -0
- data/lib/fluent/counter.rb +23 -0
- data/lib/fluent/counter/base_socket.rb +46 -0
- data/lib/fluent/counter/client.rb +297 -0
- data/lib/fluent/counter/error.rb +86 -0
- data/lib/fluent/counter/mutex_hash.rb +163 -0
- data/lib/fluent/counter/server.rb +273 -0
- data/lib/fluent/counter/store.rb +205 -0
- data/lib/fluent/counter/validator.rb +145 -0
- data/lib/fluent/env.rb +1 -0
- data/lib/fluent/event_router.rb +1 -1
- data/lib/fluent/log.rb +119 -29
- data/lib/fluent/plugin/base.rb +12 -0
- data/lib/fluent/plugin/buf_file.rb +20 -16
- data/lib/fluent/plugin/buffer.rb +130 -32
- data/lib/fluent/plugin/buffer/file_chunk.rb +23 -4
- data/lib/fluent/plugin/compressable.rb +1 -1
- data/lib/fluent/plugin/filter_grep.rb +135 -21
- data/lib/fluent/plugin/filter_parser.rb +13 -2
- data/lib/fluent/plugin/filter_record_transformer.rb +16 -14
- data/lib/fluent/plugin/formatter_stdout.rb +3 -2
- data/lib/fluent/plugin/formatter_tsv.rb +5 -1
- data/lib/fluent/plugin/in_debug_agent.rb +8 -1
- data/lib/fluent/plugin/in_forward.rb +1 -1
- data/lib/fluent/plugin/in_http.rb +84 -3
- data/lib/fluent/plugin/in_monitor_agent.rb +7 -1
- data/lib/fluent/plugin/in_syslog.rb +31 -10
- data/lib/fluent/plugin/in_tail.rb +142 -53
- data/lib/fluent/plugin/in_tcp.rb +5 -6
- data/lib/fluent/plugin/in_udp.rb +6 -2
- data/lib/fluent/plugin/in_unix.rb +1 -1
- data/lib/fluent/plugin/multi_output.rb +1 -0
- data/lib/fluent/plugin/out_copy.rb +25 -2
- data/lib/fluent/plugin/out_file.rb +26 -7
- data/lib/fluent/plugin/out_forward.rb +81 -42
- data/lib/fluent/plugin/out_secondary_file.rb +2 -2
- data/lib/fluent/plugin/out_stdout.rb +0 -1
- data/lib/fluent/plugin/out_stream.rb +1 -1
- data/lib/fluent/plugin/output.rb +221 -57
- data/lib/fluent/plugin/parser_apache.rb +1 -1
- data/lib/fluent/plugin/parser_apache2.rb +5 -1
- data/lib/fluent/plugin/parser_apache_error.rb +1 -1
- data/lib/fluent/plugin/parser_json.rb +10 -3
- data/lib/fluent/plugin/parser_ltsv.rb +7 -0
- data/lib/fluent/plugin/parser_multiline.rb +2 -1
- data/lib/fluent/plugin/parser_nginx.rb +1 -1
- data/lib/fluent/plugin/parser_none.rb +1 -0
- data/lib/fluent/plugin/parser_regexp.rb +15 -14
- data/lib/fluent/plugin/parser_syslog.rb +9 -5
- data/lib/fluent/plugin_helper.rb +2 -0
- data/lib/fluent/plugin_helper/cert_option.rb +28 -9
- data/lib/fluent/plugin_helper/compat_parameters.rb +3 -1
- data/lib/fluent/plugin_helper/counter.rb +51 -0
- data/lib/fluent/plugin_helper/event_loop.rb +9 -0
- data/lib/fluent/plugin_helper/record_accessor.rb +210 -0
- data/lib/fluent/plugin_helper/retry_state.rb +15 -7
- data/lib/fluent/plugin_helper/server.rb +87 -25
- data/lib/fluent/plugin_helper/socket_option.rb +5 -2
- data/lib/fluent/plugin_helper/timer.rb +8 -7
- data/lib/fluent/root_agent.rb +18 -9
- data/lib/fluent/supervisor.rb +63 -23
- data/lib/fluent/system_config.rb +30 -2
- data/lib/fluent/test/helpers.rb +1 -1
- data/lib/fluent/time.rb +15 -7
- data/lib/fluent/timezone.rb +26 -2
- data/lib/fluent/version.rb +1 -1
- data/templates/new_gem/README.md.erb +2 -2
- data/templates/new_gem/lib/fluent/plugin/filter.rb.erb +1 -1
- data/templates/new_gem/lib/fluent/plugin/input.rb.erb +1 -1
- data/templates/new_gem/lib/fluent/plugin/output.rb.erb +1 -1
- data/templates/new_gem/lib/fluent/plugin/parser.rb.erb +4 -4
- data/test/command/test_ca_generate.rb +70 -0
- data/test/command/test_fluentd.rb +2 -2
- data/test/command/test_plugin_config_formatter.rb +8 -7
- data/test/command/test_plugin_generator.rb +65 -39
- data/test/config/test_config_parser.rb +7 -2
- data/test/config/test_configurable.rb +7 -2
- data/test/config/test_configure_proxy.rb +41 -3
- data/test/config/test_dsl.rb +10 -10
- data/test/config/test_element.rb +10 -0
- data/test/config/test_literal_parser.rb +8 -0
- data/test/config/test_plugin_configuration.rb +56 -0
- data/test/config/test_system_config.rb +19 -1
- data/test/config/test_types.rb +37 -0
- data/test/counter/test_client.rb +559 -0
- data/test/counter/test_error.rb +44 -0
- data/test/counter/test_mutex_hash.rb +179 -0
- data/test/counter/test_server.rb +589 -0
- data/test/counter/test_store.rb +258 -0
- data/test/counter/test_validator.rb +137 -0
- data/test/plugin/test_buf_file.rb +124 -0
- data/test/plugin/test_buffer.rb +3 -2
- data/test/plugin/test_filter_grep.rb +580 -2
- data/test/plugin/test_filter_parser.rb +33 -2
- data/test/plugin/test_filter_record_transformer.rb +22 -1
- data/test/plugin/test_formatter_ltsv.rb +3 -0
- data/test/plugin/test_formatter_tsv.rb +68 -0
- data/test/plugin/test_in_debug_agent.rb +21 -0
- data/test/plugin/test_in_exec.rb +3 -5
- data/test/plugin/test_in_http.rb +178 -0
- data/test/plugin/test_in_monitor_agent.rb +1 -1
- data/test/plugin/test_in_syslog.rb +64 -0
- data/test/plugin/test_in_tail.rb +116 -6
- data/test/plugin/test_in_tcp.rb +21 -0
- data/test/plugin/test_in_udp.rb +78 -0
- data/test/plugin/test_metadata.rb +89 -0
- data/test/plugin/test_out_copy.rb +31 -0
- data/test/plugin/test_out_file.rb +108 -2
- data/test/plugin/test_out_forward.rb +195 -2
- data/test/plugin/test_out_secondary_file.rb +14 -0
- data/test/plugin/test_output.rb +159 -45
- data/test/plugin/test_output_as_buffered.rb +19 -0
- data/test/plugin/test_output_as_buffered_backup.rb +307 -0
- data/test/plugin/test_output_as_buffered_retries.rb +70 -0
- data/test/plugin/test_output_as_buffered_secondary.rb +1 -1
- data/test/plugin/test_parser_apache2.rb +1 -0
- data/test/plugin/test_parser_labeled_tsv.rb +17 -0
- data/test/plugin/test_parser_nginx.rb +40 -0
- data/test/plugin/test_parser_regexp.rb +6 -7
- data/test/plugin/test_parser_syslog.rb +155 -5
- data/test/plugin_helper/test_child_process.rb +4 -4
- data/test/plugin_helper/test_compat_parameters.rb +22 -0
- data/test/plugin_helper/test_record_accessor.rb +197 -0
- data/test/plugin_helper/test_retry_state.rb +20 -0
- data/test/plugin_helper/test_server.rb +30 -2
- data/test/test_config.rb +3 -3
- data/test/test_configdsl.rb +2 -2
- data/test/test_log.rb +51 -1
- data/test/test_root_agent.rb +33 -0
- data/test/test_supervisor.rb +105 -0
- metadata +68 -8
- data/COPYING +0 -14
data/test/config/test_element.rb
CHANGED
@@ -2,6 +2,7 @@ require_relative '../helper'
|
|
2
2
|
require 'fluent/config/element'
|
3
3
|
require 'fluent/config/configure_proxy'
|
4
4
|
require 'fluent/configurable'
|
5
|
+
require 'pp'
|
5
6
|
|
6
7
|
class TestConfigElement < ::Test::Unit::TestCase
|
7
8
|
def element(name = 'ROOT', arg = '', attrs = {}, elements = [], unused = nil)
|
@@ -463,4 +464,13 @@ CONF
|
|
463
464
|
assert_false e.for_another_worker?
|
464
465
|
end
|
465
466
|
end
|
467
|
+
|
468
|
+
sub_test_case '#pretty_print' do
|
469
|
+
test 'prints inspect to pp object' do
|
470
|
+
q = PP.new
|
471
|
+
e = element()
|
472
|
+
e.pretty_print(q)
|
473
|
+
assert_equal e.inspect, q.output
|
474
|
+
end
|
475
|
+
end
|
466
476
|
end
|
@@ -232,6 +232,14 @@ module Fluent::Config
|
|
232
232
|
test("\"\#{\n=begin\n}\"") { assert_parse_error("\"\#{\n=begin\n}\"") } # error in embedded ruby code
|
233
233
|
test('"#{v1}foo#{v2}"') { assert_text_parsed_as("#{v1}foo#{v2}", '"#{v1}foo#{v2}"') }
|
234
234
|
test('"#{1+1}foo#{2+2}bar"') { assert_text_parsed_as("#{1+1}foo#{2+2}bar", '"#{1+1}foo#{2+2}bar"') }
|
235
|
+
test('"foo#{hostname}"') { assert_text_parsed_as("foo#{Socket.gethostname}", '"foo#{hostname}"') }
|
236
|
+
test('"foo#{worker_id}"') {
|
237
|
+
ENV.delete('SERVERENGINE_WORKER_ID')
|
238
|
+
assert_text_parsed_as("foo", '"foo#{worker_id}"')
|
239
|
+
ENV['SERVERENGINE_WORKER_ID'] = '1'
|
240
|
+
assert_text_parsed_as("foo1", '"foo#{worker_id}"')
|
241
|
+
ENV.delete('SERVERENGINE_WORKER_ID')
|
242
|
+
}
|
235
243
|
end
|
236
244
|
|
237
245
|
sub_test_case 'array parsing' do
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require_relative '../helper'
|
2
|
+
require 'fluent/plugin/input'
|
3
|
+
require 'fluent/test/driver/input'
|
4
|
+
|
5
|
+
module ConfigurationForPlugins
|
6
|
+
class AllBooleanParams < Fluent::Plugin::Input
|
7
|
+
config_param :flag1, :bool, default: true
|
8
|
+
config_param :flag2, :bool, default: true
|
9
|
+
config_param :flag3, :bool, default: false
|
10
|
+
config_param :flag4, :bool, default: false
|
11
|
+
|
12
|
+
config_section :child, param_name: :children, multi: true, required: true do
|
13
|
+
config_param :flag1, :bool, default: true
|
14
|
+
config_param :flag2, :bool, default: true
|
15
|
+
config_param :flag3, :bool, default: false
|
16
|
+
config_param :flag4, :bool, default: false
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class BooleanParamsWithoutValue < ::Test::Unit::TestCase
|
21
|
+
CONFIG = <<CONFIG
|
22
|
+
flag1
|
23
|
+
flag2 # yaaaaaaaaaay
|
24
|
+
flag3
|
25
|
+
flag4 # yaaaaaaaaaay
|
26
|
+
<child>
|
27
|
+
flag1
|
28
|
+
flag2 # yaaaaaaaaaay
|
29
|
+
flag3
|
30
|
+
flag4 # yaaaaaaaaaay
|
31
|
+
</child>
|
32
|
+
<child>
|
33
|
+
flag1 # yaaaaaaaaaay
|
34
|
+
flag2
|
35
|
+
flag3 # yaaaaaaaaaay
|
36
|
+
flag4
|
37
|
+
</child>
|
38
|
+
# with following whitespace
|
39
|
+
<child>
|
40
|
+
flag1
|
41
|
+
flag2
|
42
|
+
flag3
|
43
|
+
flag4
|
44
|
+
</child>
|
45
|
+
CONFIG
|
46
|
+
|
47
|
+
test 'create plugin via driver' do
|
48
|
+
d = Fluent::Test::Driver::Input.new(AllBooleanParams)
|
49
|
+
d.configure(CONFIG)
|
50
|
+
assert_equal([true] * 4, [d.instance.flag1, d.instance.flag2, d.instance.flag3, d.instance.flag4])
|
51
|
+
num_of_sections = 3
|
52
|
+
assert_equal num_of_sections, d.instance.children.size
|
53
|
+
assert_equal([true] * (num_of_sections * 4), d.instance.children.map{|c| [c.flag1, c.flag2, c.flag3, c.flag4]}.flatten)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -7,7 +7,7 @@ require 'fluent/system_config'
|
|
7
7
|
module Fluent::Config
|
8
8
|
class FakeLoggerInitializer
|
9
9
|
attr_accessor :level
|
10
|
-
def
|
10
|
+
def initialize
|
11
11
|
@level = nil
|
12
12
|
end
|
13
13
|
end
|
@@ -55,6 +55,8 @@ module Fluent::Config
|
|
55
55
|
assert_nil(sc.emit_error_log_interval)
|
56
56
|
assert_nil(sc.suppress_config_dump)
|
57
57
|
assert_nil(sc.without_source)
|
58
|
+
assert_equal(:text, sc.log.format)
|
59
|
+
assert_equal('%Y-%m-%d %H:%M:%S %z', sc.log.time_format)
|
58
60
|
assert_equal(1, s.instance_variable_get(:@workers))
|
59
61
|
assert_nil(s.instance_variable_get(:@root_dir))
|
60
62
|
assert_equal(Fluent::Log::LEVEL_INFO, s.instance_variable_get(:@log_level))
|
@@ -91,6 +93,22 @@ module Fluent::Config
|
|
91
93
|
assert_not_nil(s.instance_variable_get("@#{key}"))
|
92
94
|
end
|
93
95
|
|
96
|
+
test "log parameters" do
|
97
|
+
conf = parse_text(<<-EOS)
|
98
|
+
<system>
|
99
|
+
<log>
|
100
|
+
format json
|
101
|
+
time_format %Y
|
102
|
+
</log>
|
103
|
+
</system>
|
104
|
+
EOS
|
105
|
+
s = FakeSupervisor.new
|
106
|
+
sc = Fluent::SystemConfig.new(conf)
|
107
|
+
sc.apply(s)
|
108
|
+
assert_equal(:json, sc.log.format)
|
109
|
+
assert_equal('%Y', sc.log.time_format)
|
110
|
+
end
|
111
|
+
|
94
112
|
data(
|
95
113
|
'foo' => ['foo', 'bar'],
|
96
114
|
'hoge' => ['hoge', 'fuga'],
|
data/test/config/test_types.rb
CHANGED
@@ -61,6 +61,34 @@ class TestConfigTypes < ::Test::Unit::TestCase
|
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
64
|
+
sub_test_case 'Config.regexp_value' do
|
65
|
+
data("empty" => [//, "//"],
|
66
|
+
"plain" => [/regexp/, "/regexp/"],
|
67
|
+
"zero width" => [/^$/, "/^$/"],
|
68
|
+
"character classes" => [/[a-z]/, "/[a-z]/"],
|
69
|
+
"meta charactersx" => [/.+.*?\d\w\s\S/, '/.+.*?\d\w\s\S/'])
|
70
|
+
test 'normal case' do |(expected, str)|
|
71
|
+
assert_equal(expected, Config.regexp_value(str))
|
72
|
+
end
|
73
|
+
|
74
|
+
data("empty" => [//, ""],
|
75
|
+
"plain" => [/regexp/, "regexp"],
|
76
|
+
"zero width" => [/^$/, "^$"],
|
77
|
+
"character classes" => [/[a-z]/, "[a-z]"],
|
78
|
+
"meta charactersx" => [/.+.*?\d\w\s\S/, '.+.*?\d\w\s\S'])
|
79
|
+
test 'w/o slashes' do |(expected, str)|
|
80
|
+
assert_equal(expected, Config.regexp_value(str))
|
81
|
+
end
|
82
|
+
|
83
|
+
data("missing right slash" => "/regexp",
|
84
|
+
"too many options" => "/regexp/imx",)
|
85
|
+
test 'invalid regexp' do |(str)|
|
86
|
+
assert_raise(Fluent::ConfigError.new("invalid regexp: missing right slash: #{str}")) do
|
87
|
+
Config.regexp_value(str)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
64
92
|
sub_test_case 'type converters for config_param definitions' do
|
65
93
|
test 'string' do
|
66
94
|
assert_equal 'test', Config::STRING_TYPE.call('test', {})
|
@@ -134,6 +162,15 @@ class TestConfigTypes < ::Test::Unit::TestCase
|
|
134
162
|
assert_equal 86400, Config::TIME_TYPE.call('1d', {})
|
135
163
|
end
|
136
164
|
|
165
|
+
data("empty" => [//, "//"],
|
166
|
+
"plain" => [/regexp/, "/regexp/"],
|
167
|
+
"zero width" => [/^$/, "/^$/"],
|
168
|
+
"character classes" => [/[a-z]/, "/[a-z]/"],
|
169
|
+
"meta charactersx" => [/.+.*?\d\w\s\S/, '/.+.*?\d\w\s\S/'])
|
170
|
+
test 'regexp' do |(expected, str)|
|
171
|
+
assert_equal(expected, Config::REGEXP_TYPE.call(str, {}))
|
172
|
+
end
|
173
|
+
|
137
174
|
test 'hash' do
|
138
175
|
assert_equal({"x"=>"v","k"=>1}, Config::HASH_TYPE.call('{"x":"v","k":1}', {}))
|
139
176
|
assert_equal({"x"=>"v","k"=>"1"}, Config::HASH_TYPE.call('x:v,k:1', {}))
|
@@ -0,0 +1,559 @@
|
|
1
|
+
require_relative '../helper'
|
2
|
+
require 'fluent/counter/client'
|
3
|
+
require 'fluent/counter/store'
|
4
|
+
require 'fluent/counter/server'
|
5
|
+
require 'flexmock/test_unit'
|
6
|
+
require 'timecop'
|
7
|
+
|
8
|
+
class CounterClientTest < ::Test::Unit::TestCase
|
9
|
+
TEST_ADDR = '127.0.0.1'
|
10
|
+
TEST_PORT = '8277'
|
11
|
+
|
12
|
+
setup do
|
13
|
+
# timecop isn't compatible with EventTime
|
14
|
+
t = Time.parse('2016-09-22 16:59:59 +0900')
|
15
|
+
Timecop.freeze(t)
|
16
|
+
@now = Fluent::EventTime.now
|
17
|
+
|
18
|
+
@options = {
|
19
|
+
addr: TEST_ADDR,
|
20
|
+
port: TEST_PORT,
|
21
|
+
log: $log,
|
22
|
+
}
|
23
|
+
|
24
|
+
@server_name = 'server1'
|
25
|
+
@scope = "worker1\tplugin1"
|
26
|
+
@loop = Coolio::Loop.new
|
27
|
+
@server = Fluent::Counter::Server.new(@server_name, @options).start
|
28
|
+
@client = Fluent::Counter::Client.new(@loop, @options).start
|
29
|
+
end
|
30
|
+
|
31
|
+
teardown do
|
32
|
+
Timecop.return
|
33
|
+
@server.stop
|
34
|
+
@client.stop
|
35
|
+
end
|
36
|
+
|
37
|
+
test 'Callable API' do
|
38
|
+
[:establish, :init, :delete, :inc, :reset, :get].each do |m|
|
39
|
+
assert_true @client.respond_to?(m)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
sub_test_case 'on_message' do
|
44
|
+
setup do
|
45
|
+
@future = flexmock('future')
|
46
|
+
@client.instance_variable_set(:@responses, { 1 => @future })
|
47
|
+
end
|
48
|
+
|
49
|
+
test 'call a set method to a corresponding object' do
|
50
|
+
@future.should_receive(:set).once.with(Hash)
|
51
|
+
@client.send(:on_message, { 'id' => 1 })
|
52
|
+
end
|
53
|
+
|
54
|
+
test "output a warning log when passed id doesn't exist" do
|
55
|
+
data = { 'id' => 2 }
|
56
|
+
mock($log).warn("Receiving missing id data: #{data}")
|
57
|
+
@client.send(:on_message, data)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def extract_value_from_server(server, scope, name)
|
62
|
+
store = server.instance_variable_get(:@store).instance_variable_get(:@storage).instance_variable_get(:@store)
|
63
|
+
key = Fluent::Counter::Store.gen_key(scope, name)
|
64
|
+
store[key]
|
65
|
+
end
|
66
|
+
|
67
|
+
def travel(sec)
|
68
|
+
# Since Timecop.travel() causes test failures on Windows/AppVeyor by inducing
|
69
|
+
# rounding errors to Time.now, we need to use Timecop.freeze() instead.
|
70
|
+
Timecop.freeze(Time.now + sec)
|
71
|
+
end
|
72
|
+
|
73
|
+
sub_test_case 'establish' do
|
74
|
+
test 'establish a scope' do
|
75
|
+
@client.establish(@scope)
|
76
|
+
assert_equal "#{@server_name}\t#{@scope}", @client.instance_variable_get(:@scope)
|
77
|
+
end
|
78
|
+
|
79
|
+
data(
|
80
|
+
empty: '',
|
81
|
+
invalid_string: '_scope',
|
82
|
+
invalid_string2: 'Scope'
|
83
|
+
)
|
84
|
+
test 'raise an error when passed scope is invalid' do |scope|
|
85
|
+
assert_raise do
|
86
|
+
@client.establish(scope)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
sub_test_case 'init' do
|
92
|
+
setup do
|
93
|
+
@client.instance_variable_set(:@scope, @scope)
|
94
|
+
end
|
95
|
+
|
96
|
+
data(
|
97
|
+
numeric_type: [
|
98
|
+
{ name: 'key', reset_interval: 20, type: 'numeric' }, 0
|
99
|
+
],
|
100
|
+
float_type: [
|
101
|
+
{ name: 'key', reset_interval: 20, type: 'float' }, 0.0
|
102
|
+
],
|
103
|
+
integer_type: [
|
104
|
+
{ name: 'key', reset_interval: 20, type: 'integer' }, 0
|
105
|
+
]
|
106
|
+
)
|
107
|
+
test 'create a value' do |(param, initial_value)|
|
108
|
+
assert_nil extract_value_from_server(@server, @scope, param[:name])
|
109
|
+
|
110
|
+
response = @client.init(param).get
|
111
|
+
data = response.data.first
|
112
|
+
|
113
|
+
assert_nil response.errors
|
114
|
+
assert_equal param[:name], data['name']
|
115
|
+
assert_equal param[:reset_interval], data['reset_interval']
|
116
|
+
assert_equal param[:type], data['type']
|
117
|
+
assert_equal initial_value, data['current']
|
118
|
+
assert_equal initial_value, data['total']
|
119
|
+
|
120
|
+
v = extract_value_from_server(@server, @scope, param[:name])
|
121
|
+
assert_equal param[:name], v['name']
|
122
|
+
assert_equal param[:reset_interval], v['reset_interval']
|
123
|
+
assert_equal param[:type], v['type']
|
124
|
+
assert_equal initial_value, v['total']
|
125
|
+
assert_equal initial_value, v['current']
|
126
|
+
end
|
127
|
+
|
128
|
+
test 'raise an error when @scope is nil' do
|
129
|
+
@client.instance_variable_set(:@scope, nil)
|
130
|
+
assert_raise 'Call `establish` method to get a `scope` before calling this method' do
|
131
|
+
@client.init(name: 'key1', reset_interval: 10).get
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
data(
|
136
|
+
already_exist_key: [
|
137
|
+
{ name: 'key1', reset_interval: 10 },
|
138
|
+
{ 'code' => 'invalid_params', 'message' => "worker1\tplugin1\tkey1 already exists in counter" }
|
139
|
+
],
|
140
|
+
missing_name: [
|
141
|
+
{ reset_interval: 10 },
|
142
|
+
{ 'code' => 'invalid_params', 'message' => '`name` is required' },
|
143
|
+
],
|
144
|
+
missing_reset_interval: [
|
145
|
+
{ name: 'key' },
|
146
|
+
{ 'code' => 'invalid_params', 'message' => '`reset_interval` is required' },
|
147
|
+
],
|
148
|
+
invalid_name: [
|
149
|
+
{ name: '\tkey' },
|
150
|
+
{ 'code' => 'invalid_params', 'message' => '`name` is the invalid format' }
|
151
|
+
]
|
152
|
+
)
|
153
|
+
test 'return an error object' do |(param, expected_error)|
|
154
|
+
@client.init(:name => 'key1', :reset_interval => 10).get
|
155
|
+
response = @client.init(param).get
|
156
|
+
errors = response.errors.first
|
157
|
+
|
158
|
+
assert_empty response.data
|
159
|
+
assert_equal expected_error, errors
|
160
|
+
|
161
|
+
assert_raise {
|
162
|
+
@client.init(param).wait
|
163
|
+
}
|
164
|
+
end
|
165
|
+
|
166
|
+
test 'return an existing value when passed key already exists and ignore option is true' do
|
167
|
+
res1 = @client.init(name: 'key1', reset_interval: 10).get
|
168
|
+
res2 = nil
|
169
|
+
assert_nothing_raised do
|
170
|
+
res2 = @client.init({ name: 'key1', reset_interval: 10 }, options: { ignore: true }).get
|
171
|
+
end
|
172
|
+
assert_equal res1.data, res2.data
|
173
|
+
end
|
174
|
+
|
175
|
+
test 'return an error object and data object' do
|
176
|
+
param = { name: 'key1', reset_interval: 10 }
|
177
|
+
param2 = { name: 'key2', reset_interval: 10 }
|
178
|
+
@client.init(param).get
|
179
|
+
|
180
|
+
response = @client.init([param2, param]).get
|
181
|
+
data = response.data.first
|
182
|
+
error = response.errors.first
|
183
|
+
|
184
|
+
assert_equal param2[:name], data['name']
|
185
|
+
assert_equal param2[:reset_interval], data['reset_interval']
|
186
|
+
|
187
|
+
assert_equal 'invalid_params', error['code']
|
188
|
+
assert_equal "#{@scope}\t#{param[:name]} already exists in counter", error['message']
|
189
|
+
end
|
190
|
+
|
191
|
+
test 'return a future object when async call' do
|
192
|
+
param = { name: 'key', reset_interval: 10 }
|
193
|
+
r = @client.init(param)
|
194
|
+
assert_true r.is_a?(Fluent::Counter::Future)
|
195
|
+
assert_nil r.errors
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
sub_test_case 'delete' do
|
200
|
+
setup do
|
201
|
+
@client.instance_variable_set(:@scope, @scope)
|
202
|
+
@name = 'key'
|
203
|
+
@key = Fluent::Counter::Store.gen_key(@scope, @name)
|
204
|
+
|
205
|
+
@init_obj = { name: @name, reset_interval: 20, type: 'numeric' }
|
206
|
+
@client.init(@init_obj).get
|
207
|
+
end
|
208
|
+
|
209
|
+
test 'delete a value' do
|
210
|
+
assert extract_value_from_server(@server, @scope, @name)
|
211
|
+
|
212
|
+
response = @client.delete(@name).get
|
213
|
+
v = response.data.first
|
214
|
+
|
215
|
+
assert_nil response.errors
|
216
|
+
assert_equal @init_obj[:name], v['name']
|
217
|
+
assert_equal @init_obj[:type], v['type']
|
218
|
+
assert_equal @init_obj[:reset_interval], v['reset_interval']
|
219
|
+
|
220
|
+
assert_nil extract_value_from_server(@server, @scope, @name)
|
221
|
+
end
|
222
|
+
|
223
|
+
test 'raise an error when @scope is nil' do
|
224
|
+
@client.instance_variable_set(:@scope, nil)
|
225
|
+
assert_raise 'Call `establish` method to get a `scope` before calling this method' do
|
226
|
+
@client.delete(@name).get
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
data(
|
231
|
+
key_not_found: [
|
232
|
+
'key2',
|
233
|
+
{ 'code' => 'unknown_key', 'message' => "`worker1\tplugin1\tkey2` doesn't exist in counter" }
|
234
|
+
],
|
235
|
+
invalid_key: [
|
236
|
+
'\tkey',
|
237
|
+
{ 'code' => 'invalid_params', 'message' => '`key` is the invalid format' }
|
238
|
+
]
|
239
|
+
)
|
240
|
+
test 'return an error object' do |(param, expected_error)|
|
241
|
+
response = @client.delete(param).get
|
242
|
+
errors = response.errors.first
|
243
|
+
|
244
|
+
assert_empty response.data
|
245
|
+
assert_equal expected_error, errors
|
246
|
+
end
|
247
|
+
|
248
|
+
test 'return an error object and data object' do
|
249
|
+
unknown_name = 'key2'
|
250
|
+
|
251
|
+
response = @client.delete(@name, unknown_name).get
|
252
|
+
data = response.data.first
|
253
|
+
error = response.errors.first
|
254
|
+
|
255
|
+
assert_equal @name, data['name']
|
256
|
+
assert_equal @init_obj[:reset_interval], data['reset_interval']
|
257
|
+
|
258
|
+
assert_equal 'unknown_key', error['code']
|
259
|
+
assert_equal "`#{@scope}\t#{unknown_name}` doesn't exist in counter", error['message']
|
260
|
+
|
261
|
+
assert_nil extract_value_from_server(@server, @scope, @name)
|
262
|
+
end
|
263
|
+
|
264
|
+
test 'return a future object when async call' do
|
265
|
+
r = @client.delete(@name)
|
266
|
+
assert_true r.is_a?(Fluent::Counter::Future)
|
267
|
+
assert_nil r.errors
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
sub_test_case 'inc' do
|
272
|
+
setup do
|
273
|
+
@client.instance_variable_set(:@scope, @scope)
|
274
|
+
@name = 'key'
|
275
|
+
@key = Fluent::Counter::Store.gen_key(@scope, @name)
|
276
|
+
|
277
|
+
@init_obj = { name: @name, reset_interval: 20, type: 'numeric' }
|
278
|
+
@client.init(@init_obj).get
|
279
|
+
end
|
280
|
+
|
281
|
+
test 'increment a value' do
|
282
|
+
v = extract_value_from_server(@server, @scope, @name)
|
283
|
+
assert_equal 0, v['total']
|
284
|
+
assert_equal 0, v['current']
|
285
|
+
|
286
|
+
travel(1)
|
287
|
+
inc_obj = { name: @name, value: 10 }
|
288
|
+
@client.inc(inc_obj).get
|
289
|
+
|
290
|
+
v = extract_value_from_server(@server, @scope, @name)
|
291
|
+
assert_equal inc_obj[:value], v['total']
|
292
|
+
assert_equal inc_obj[:value], v['current']
|
293
|
+
assert_equal (@now + 1), Fluent::EventTime.new(*v['last_modified_at'])
|
294
|
+
end
|
295
|
+
|
296
|
+
test 'create and increment a value when force option is true' do
|
297
|
+
name = 'new_key'
|
298
|
+
param = { name: name, value: 11, reset_interval: 1 }
|
299
|
+
|
300
|
+
assert_nil extract_value_from_server(@server, @scope, name)
|
301
|
+
|
302
|
+
@client.inc(param, options: { force: true }).get
|
303
|
+
|
304
|
+
v = extract_value_from_server(@server, @scope, name)
|
305
|
+
assert v
|
306
|
+
assert_equal param[:name], v['name']
|
307
|
+
assert_equal 1, v['reset_interval']
|
308
|
+
assert_equal param[:value], v['current']
|
309
|
+
assert_equal param[:value], v['total']
|
310
|
+
end
|
311
|
+
|
312
|
+
test 'raise an error when @scope is nil' do
|
313
|
+
@client.instance_variable_set(:@scope, nil)
|
314
|
+
assert_raise 'Call `establish` method to get a `scope` before calling this method' do
|
315
|
+
@client.inc(name: 'name', value: 1).get
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
data(
|
320
|
+
not_exist_key: [
|
321
|
+
{ name: 'key2', value: 10 },
|
322
|
+
{ 'code' => 'unknown_key', 'message' => "`worker1\tplugin1\tkey2` doesn't exist in counter" }
|
323
|
+
],
|
324
|
+
missing_name: [
|
325
|
+
{ value: 10 },
|
326
|
+
{ 'code' => 'invalid_params', 'message' => '`name` is required' },
|
327
|
+
],
|
328
|
+
missing_value: [
|
329
|
+
{ name: 'key' },
|
330
|
+
{ 'code' => 'invalid_params', 'message' => '`value` is required' },
|
331
|
+
],
|
332
|
+
invalid_name: [
|
333
|
+
{ name: '\tkey' },
|
334
|
+
{ 'code' => 'invalid_params', 'message' => '`name` is the invalid format' }
|
335
|
+
]
|
336
|
+
)
|
337
|
+
test 'return an error object' do |(param, expected_error)|
|
338
|
+
response = @client.inc(param).get
|
339
|
+
errors = response.errors.first
|
340
|
+
assert_empty response.data
|
341
|
+
assert_equal expected_error, errors
|
342
|
+
end
|
343
|
+
|
344
|
+
test 'return an error object and data object' do
|
345
|
+
parmas = [
|
346
|
+
{ name: @name, value: 10 },
|
347
|
+
{ name: 'unknown_key', value: 9 },
|
348
|
+
]
|
349
|
+
response = @client.inc(parmas).get
|
350
|
+
|
351
|
+
data = response.data.first
|
352
|
+
error = response.errors.first
|
353
|
+
|
354
|
+
assert_equal @name, data['name']
|
355
|
+
assert_equal 10, data['current']
|
356
|
+
assert_equal 10, data['total']
|
357
|
+
|
358
|
+
assert_equal 'unknown_key', error['code']
|
359
|
+
assert_equal "`#{@scope}\tunknown_key` doesn't exist in counter", error['message']
|
360
|
+
end
|
361
|
+
|
362
|
+
test 'return a future object when async call' do
|
363
|
+
param = { name: 'key', value: 10 }
|
364
|
+
r = @client.inc(param)
|
365
|
+
assert_true r.is_a?(Fluent::Counter::Future)
|
366
|
+
assert_nil r.errors
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
370
|
+
sub_test_case 'get' do
|
371
|
+
setup do
|
372
|
+
@client.instance_variable_set(:@scope, @scope)
|
373
|
+
@name = 'key'
|
374
|
+
|
375
|
+
@init_obj = { name: @name, reset_interval: 20, type: 'numeric' }
|
376
|
+
@client.init(@init_obj).get
|
377
|
+
end
|
378
|
+
|
379
|
+
test 'get a value' do
|
380
|
+
v1 = extract_value_from_server(@server, @scope, @name)
|
381
|
+
v2 = @client.get(@name).data.first
|
382
|
+
|
383
|
+
assert_equal v1['name'], v2['name']
|
384
|
+
assert_equal v1['current'], v2['current']
|
385
|
+
assert_equal v1['total'], v2['total']
|
386
|
+
assert_equal v1['type'], v2['type']
|
387
|
+
end
|
388
|
+
|
389
|
+
test 'raise an error when @scope is nil' do
|
390
|
+
@client.instance_variable_set(:@scope, nil)
|
391
|
+
assert_raise 'Call `establish` method to get a `scope` before calling this method' do
|
392
|
+
@client.get(@name).get
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
396
|
+
data(
|
397
|
+
key_not_found: [
|
398
|
+
'key2',
|
399
|
+
{ 'code' => 'unknown_key', 'message' => "`worker1\tplugin1\tkey2` doesn't exist in counter" }
|
400
|
+
],
|
401
|
+
invalid_key: [
|
402
|
+
'\tkey',
|
403
|
+
{ 'code' => 'invalid_params', 'message' => '`key` is the invalid format' }
|
404
|
+
]
|
405
|
+
)
|
406
|
+
test 'return an error object' do |(param, expected_error)|
|
407
|
+
response = @client.get(param).get
|
408
|
+
errors = response.errors.first
|
409
|
+
assert_empty response.data
|
410
|
+
assert_equal expected_error, errors
|
411
|
+
end
|
412
|
+
|
413
|
+
test 'return an error object and data object' do
|
414
|
+
unknown_name = 'key2'
|
415
|
+
|
416
|
+
response = @client.get(@name, unknown_name).get
|
417
|
+
data = response.data.first
|
418
|
+
error = response.errors.first
|
419
|
+
|
420
|
+
assert_equal @name, data['name']
|
421
|
+
assert_equal @init_obj[:reset_interval], data['reset_interval']
|
422
|
+
|
423
|
+
assert_equal 'unknown_key', error['code']
|
424
|
+
assert_equal "`#{@scope}\t#{unknown_name}` doesn't exist in counter", error['message']
|
425
|
+
end
|
426
|
+
|
427
|
+
test 'return a future object when async call' do
|
428
|
+
r = @client.get(@name)
|
429
|
+
assert_true r.is_a?(Fluent::Counter::Future)
|
430
|
+
assert_nil r.errors
|
431
|
+
end
|
432
|
+
end
|
433
|
+
|
434
|
+
sub_test_case 'reset' do
|
435
|
+
setup do
|
436
|
+
@client.instance_variable_set(:@scope, @scope)
|
437
|
+
@name = 'key'
|
438
|
+
@key = Fluent::Counter::Store.gen_key(@scope, @name)
|
439
|
+
|
440
|
+
@init_obj = { name: @name, reset_interval: 5, type: 'numeric' }
|
441
|
+
@client.init(@init_obj).get
|
442
|
+
@inc_obj = { name: @name, value: 10 }
|
443
|
+
@client.inc(@inc_obj).get
|
444
|
+
end
|
445
|
+
|
446
|
+
test 'reset a value after `reset_interval` passed' do
|
447
|
+
v1 = extract_value_from_server(@server, @scope, @name)
|
448
|
+
assert_equal @inc_obj[:value], v1['total']
|
449
|
+
assert_equal @inc_obj[:value], v1['current']
|
450
|
+
assert_equal @now, Fluent::EventTime.new(*v1['last_reset_at'])
|
451
|
+
|
452
|
+
travel_sec = 6 # greater than reset_interval
|
453
|
+
travel(travel_sec)
|
454
|
+
|
455
|
+
v2 = @client.reset(@name).get
|
456
|
+
data = v2.data.first
|
457
|
+
|
458
|
+
c = data['counter_data']
|
459
|
+
|
460
|
+
assert_equal travel_sec, data['elapsed_time']
|
461
|
+
assert_true data['success']
|
462
|
+
|
463
|
+
assert_equal @inc_obj[:value], c['current']
|
464
|
+
assert_equal @inc_obj[:value], c['total']
|
465
|
+
assert_equal @now, c['last_reset_at']
|
466
|
+
|
467
|
+
v1 = extract_value_from_server(@server, @scope, @name)
|
468
|
+
assert_equal 0, v1['current']
|
469
|
+
assert_equal @inc_obj[:value], v1['total']
|
470
|
+
assert_equal (@now + travel_sec), Fluent::EventTime.new(*v1['last_reset_at'])
|
471
|
+
assert_equal (@now + travel_sec), Fluent::EventTime.new(*v1['last_modified_at'])
|
472
|
+
end
|
473
|
+
|
474
|
+
test 'areturn a value object before `reset_interval` passed' do
|
475
|
+
v1 = extract_value_from_server(@server, @scope, @name)
|
476
|
+
assert_equal @inc_obj[:value], v1['total']
|
477
|
+
assert_equal @inc_obj[:value], v1['current']
|
478
|
+
assert_equal @now, Fluent::EventTime.new(*v1['last_reset_at'])
|
479
|
+
|
480
|
+
travel_sec = 4 # less than reset_interval
|
481
|
+
travel(travel_sec)
|
482
|
+
|
483
|
+
v2 = @client.reset(@name).get
|
484
|
+
data = v2.data.first
|
485
|
+
|
486
|
+
c = data['counter_data']
|
487
|
+
|
488
|
+
assert_equal travel_sec, data['elapsed_time']
|
489
|
+
assert_equal false, data['success']
|
490
|
+
|
491
|
+
assert_equal @inc_obj[:value], c['current']
|
492
|
+
assert_equal @inc_obj[:value], c['total']
|
493
|
+
assert_equal @now, c['last_reset_at']
|
494
|
+
|
495
|
+
v1 = extract_value_from_server(@server, @scope, @name)
|
496
|
+
assert_equal @inc_obj[:value], v1['current']
|
497
|
+
assert_equal @inc_obj[:value], v1['total']
|
498
|
+
assert_equal @now, Fluent::EventTime.new(*v1['last_reset_at'])
|
499
|
+
end
|
500
|
+
|
501
|
+
test 'raise an error when @scope is nil' do
|
502
|
+
@client.instance_variable_set(:@scope, nil)
|
503
|
+
assert_raise 'Call `establish` method to get a `scope` before calling this method' do
|
504
|
+
@client.reset(@name).get
|
505
|
+
end
|
506
|
+
end
|
507
|
+
|
508
|
+
data(
|
509
|
+
key_not_found: [
|
510
|
+
'key2',
|
511
|
+
{ 'code' => 'unknown_key', 'message' => "`worker1\tplugin1\tkey2` doesn't exist in counter" }
|
512
|
+
],
|
513
|
+
invalid_key: [
|
514
|
+
'\tkey',
|
515
|
+
{ 'code' => 'invalid_params', 'message' => '`key` is the invalid format' }
|
516
|
+
]
|
517
|
+
)
|
518
|
+
test 'return an error object' do |(param, expected_error)|
|
519
|
+
response = @client.reset(param).get
|
520
|
+
errors = response.errors.first
|
521
|
+
assert_empty response.data
|
522
|
+
assert_equal expected_error, errors
|
523
|
+
end
|
524
|
+
|
525
|
+
test 'return an error object and data object' do
|
526
|
+
unknown_name = 'key2'
|
527
|
+
|
528
|
+
travel_sec = 6 # greater than reset_interval
|
529
|
+
travel(travel_sec)
|
530
|
+
|
531
|
+
response = @client.reset(@name, unknown_name).get
|
532
|
+
data = response.data.first
|
533
|
+
error = response.errors.first
|
534
|
+
counter = data['counter_data']
|
535
|
+
|
536
|
+
assert_true data['success']
|
537
|
+
assert_equal travel_sec, data['elapsed_time']
|
538
|
+
assert_equal @name, counter['name']
|
539
|
+
assert_equal @init_obj[:reset_interval], counter['reset_interval']
|
540
|
+
assert_equal @inc_obj[:value], counter['total']
|
541
|
+
assert_equal @inc_obj[:value], counter['current']
|
542
|
+
|
543
|
+
assert_equal 'unknown_key', error['code']
|
544
|
+
assert_equal "`#{@scope}\t#{unknown_name}` doesn't exist in counter", error['message']
|
545
|
+
|
546
|
+
v1 = extract_value_from_server(@server, @scope, @name)
|
547
|
+
assert_equal 0, v1['current']
|
548
|
+
assert_equal @inc_obj[:value], v1['total']
|
549
|
+
assert_equal (@now + travel_sec), Fluent::EventTime.new(*v1['last_reset_at'])
|
550
|
+
assert_equal (@now + travel_sec), Fluent::EventTime.new(*v1['last_modified_at'])
|
551
|
+
end
|
552
|
+
|
553
|
+
test 'return a future object when async call' do
|
554
|
+
r = @client.reset(@name)
|
555
|
+
assert_true r.is_a?(Fluent::Counter::Future)
|
556
|
+
assert_nil r.errors
|
557
|
+
end
|
558
|
+
end
|
559
|
+
end
|