logstash-core 6.0.0.beta2-java → 6.0.0-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/gemspec_jars.rb +5 -5
- data/lib/logstash-core/logstash-core.jar +0 -0
- data/lib/logstash-core/version.rb +8 -4
- data/lib/logstash-core_jars.rb +10 -10
- data/lib/logstash/agent.rb +3 -2
- data/lib/logstash/compiler/lscl.rb +15 -3
- data/lib/logstash/config/config_ast.rb +3 -2
- data/lib/logstash/config/modules_common.rb +1 -0
- data/lib/logstash/config/source/local.rb +2 -1
- data/lib/logstash/instrument/periodic_poller/dlq.rb +8 -3
- data/lib/logstash/instrument/periodic_poller/pq.rb +7 -3
- data/lib/logstash/logging/logger.rb +4 -1
- data/lib/logstash/modules/kibana_client.rb +35 -8
- data/lib/logstash/modules/logstash_config.rb +1 -1
- data/lib/logstash/modules/settings_merger.rb +8 -2
- data/lib/logstash/pipeline.rb +10 -19
- data/lib/logstash/pipeline_action/stop.rb +1 -0
- data/lib/logstash/runner.rb +4 -1
- data/lib/logstash/util/cloud_setting_id.rb +46 -12
- data/lib/logstash/util/modules_setting_array.rb +1 -1
- data/lib/logstash/util/password.rb +2 -4
- data/lib/logstash/util/wrapped_acked_queue.rb +6 -0
- data/lib/logstash/util/wrapped_synchronous_queue.rb +6 -0
- data/lib/logstash/version.rb +8 -10
- data/logstash-core.gemspec +25 -3
- data/spec/logstash/agent/converge_spec.rb +23 -10
- data/spec/logstash/agent_spec.rb +35 -15
- data/spec/logstash/api/modules/node_stats_spec.rb +5 -1
- data/spec/logstash/compiler/compiler_spec.rb +29 -0
- data/spec/logstash/config/source/local_spec.rb +3 -2
- data/spec/logstash/event_spec.rb +57 -0
- data/spec/logstash/modules/kibana_client_spec.rb +60 -0
- data/spec/logstash/modules/logstash_config_spec.rb +7 -1
- data/spec/logstash/modules/scaffold_spec.rb +1 -1
- data/spec/logstash/modules/settings_merger_spec.rb +32 -2
- data/spec/logstash/pipeline_action/create_spec.rb +4 -1
- data/spec/logstash/pipeline_action/reload_spec.rb +4 -1
- data/spec/logstash/pipeline_dlq_commit_spec.rb +3 -1
- data/spec/logstash/pipeline_pq_file_spec.rb +5 -7
- data/spec/logstash/pipeline_spec.rb +26 -38
- data/spec/logstash/runner_spec.rb +1 -5
- data/spec/logstash/settings/modules_spec.rb +13 -2
- data/spec/logstash/settings/writable_directory_spec.rb +13 -10
- data/spec/logstash/timestamp_spec.rb +2 -2
- data/spec/logstash/util/cloud_setting_id_spec.rb +93 -0
- data/spec/support/helpers.rb +1 -1
- data/spec/support/mocks_classes.rb +14 -0
- data/spec/support/shared_contexts.rb +9 -0
- data/versions-gem-copy.yml +23 -0
- metadata +19 -14
@@ -16,7 +16,7 @@ module LogStash module Util class ModulesSettingArray
|
|
16
16
|
@original = value
|
17
17
|
# wrap passwords
|
18
18
|
@original.each do |hash|
|
19
|
-
hash.keys.select{|key| key.to_s.end_with?('password')}.each do |key|
|
19
|
+
hash.keys.select{|key| key.to_s.end_with?('password') && !hash[key].is_a?(LogStash::Util::Password)}.each do |key|
|
20
20
|
hash[key] = LogStash::Util::Password.new(hash[key])
|
21
21
|
end
|
22
22
|
end
|
@@ -1,10 +1,9 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require "logstash/namespace"
|
3
|
-
require "logstash/util"
|
4
3
|
|
5
4
|
# This class exists to quietly wrap a password string so that, when printed or
|
6
5
|
# logged, you don't accidentally print the password itself.
|
7
|
-
|
6
|
+
module LogStash module Util class Password
|
8
7
|
attr_reader :value
|
9
8
|
|
10
9
|
public
|
@@ -21,5 +20,4 @@ class LogStash::Util::Password
|
|
21
20
|
def inspect
|
22
21
|
return to_s
|
23
22
|
end # def inspect
|
24
|
-
end # class LogStash::Util::Password
|
25
|
-
|
23
|
+
end end end # class LogStash::Util::Password
|
@@ -287,6 +287,12 @@ module LogStash; module Util
|
|
287
287
|
# @cancelled[event] = true
|
288
288
|
end
|
289
289
|
|
290
|
+
def to_a
|
291
|
+
events = []
|
292
|
+
each {|e| events << e}
|
293
|
+
events
|
294
|
+
end
|
295
|
+
|
290
296
|
def each(&blk)
|
291
297
|
# take care not to cause @originals or @generated to change during iteration
|
292
298
|
|
@@ -218,6 +218,12 @@ module LogStash; module Util
|
|
218
218
|
# @cancelled[event] = true
|
219
219
|
end
|
220
220
|
|
221
|
+
def to_a
|
222
|
+
events = []
|
223
|
+
each {|e| events << e}
|
224
|
+
events
|
225
|
+
end
|
226
|
+
|
221
227
|
def each(&blk)
|
222
228
|
# take care not to cause @originals or @generated to change during iteration
|
223
229
|
@iterating = true
|
data/lib/logstash/version.rb
CHANGED
@@ -2,13 +2,11 @@
|
|
2
2
|
|
3
3
|
# The version of the logstash package (not the logstash-core gem version).
|
4
4
|
#
|
5
|
-
#
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
LOGSTASH_VERSION = "6.0.0-beta2"
|
5
|
+
# sourced from a copy of the master versions.yml file, see logstash-core/logstash-core.gemspec
|
6
|
+
if !defined?(ALL_VERSIONS)
|
7
|
+
require 'yaml'
|
8
|
+
ALL_VERSIONS = YAML.load_file(File.expand_path("../../versions-gem-copy.yml", File.dirname(__FILE__)))
|
9
|
+
end
|
10
|
+
if !defined?(LOGSTASH_VERSION)
|
11
|
+
LOGSTASH_VERSION = ALL_VERSIONS.fetch("logstash")
|
12
|
+
end
|
data/logstash-core.gemspec
CHANGED
@@ -1,6 +1,25 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
lib = File.expand_path('../lib', __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
|
5
|
+
project_versions_yaml_path = File.expand_path("../versions.yml", File.dirname(__FILE__))
|
6
|
+
if File.exist?(project_versions_yaml_path)
|
7
|
+
# we need to copy the project level versions.yml into the gem root
|
8
|
+
# to be able to package it into the gems file structure
|
9
|
+
# as the require 'logstash-core/version' loads the yaml file from within the gem root.
|
10
|
+
#
|
11
|
+
# we ignore the copy in git and we overwrite an existing file
|
12
|
+
# each time we build the logstash-core gem
|
13
|
+
original_lines = IO.readlines(project_versions_yaml_path)
|
14
|
+
original_lines << ""
|
15
|
+
original_lines << "# This is a copy the project level versions.yml into this gem's root and it is created when the gemspec is evaluated."
|
16
|
+
gem_versions_yaml_path = File.expand_path("./versions-gem-copy.yml", File.dirname(__FILE__))
|
17
|
+
File.open(gem_versions_yaml_path, 'w') do |new_file|
|
18
|
+
# create or overwrite
|
19
|
+
new_file.puts(original_lines)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
4
23
|
require 'logstash-core/version'
|
5
24
|
|
6
25
|
Gem::Specification.new do |gem|
|
@@ -11,7 +30,10 @@ Gem::Specification.new do |gem|
|
|
11
30
|
gem.homepage = "http://www.elastic.co/guide/en/logstash/current/index.html"
|
12
31
|
gem.license = "Apache License (2.0)"
|
13
32
|
|
14
|
-
gem.files = Dir.glob(
|
33
|
+
gem.files = Dir.glob(
|
34
|
+
%w(versions-gem-copy.yml logstash-core.gemspec gemspec_jars.rb lib/**/*.rb spec/**/*.rb locales/*
|
35
|
+
lib/logstash/api/init.ru lib/logstash-core/logstash-core.jar)
|
36
|
+
)
|
15
37
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
16
38
|
gem.name = "logstash-core"
|
17
39
|
gem.require_paths = ["lib"]
|
@@ -31,7 +53,7 @@ Gem::Specification.new do |gem|
|
|
31
53
|
|
32
54
|
gem.add_runtime_dependency "sinatra", '~> 1.4', '>= 1.4.6'
|
33
55
|
gem.add_runtime_dependency 'puma', '~> 2.16'
|
34
|
-
gem.add_runtime_dependency "jruby-openssl", "0.9.20" # >= 0.9.13 Required to support TLSv1.2
|
56
|
+
gem.add_runtime_dependency "jruby-openssl", ">= 0.9.20" # >= 0.9.13 Required to support TLSv1.2
|
35
57
|
gem.add_runtime_dependency "chronic_duration", "0.10.6"
|
36
58
|
|
37
59
|
# TODO(sissel): Treetop 1.5.x doesn't seem to work well, but I haven't
|
@@ -46,7 +68,7 @@ Gem::Specification.new do |gem|
|
|
46
68
|
gem.add_runtime_dependency "rubyzip", "~> 1.2.1"
|
47
69
|
gem.add_runtime_dependency "thread_safe", "~> 0.3.5" #(Apache 2.0 license)
|
48
70
|
|
49
|
-
gem.add_runtime_dependency "jrjackson", "~>
|
71
|
+
gem.add_runtime_dependency "jrjackson", "~> #{ALL_VERSIONS.fetch('jrjackson')}" #(Apache 2.0 license)
|
50
72
|
|
51
73
|
gem.add_runtime_dependency "jar-dependencies"
|
52
74
|
# as of Feb 3rd 2016, the ruby-maven gem is resolved to version 3.3.3 and that version
|
@@ -71,9 +71,16 @@ describe LogStash::Agent do
|
|
71
71
|
TestSourceLoader.new(infinite_pipeline_config, system_pipeline_config)
|
72
72
|
end
|
73
73
|
|
74
|
+
before(:each) do
|
75
|
+
@agent_task = start_agent(subject)
|
76
|
+
end
|
77
|
+
|
78
|
+
after(:each) do
|
79
|
+
@agent_task.stop!
|
80
|
+
end
|
81
|
+
|
74
82
|
describe "#running_user_defined_pipelines" do
|
75
83
|
it "returns the user defined pipelines" do
|
76
|
-
start_agent(subject)
|
77
84
|
wait_for do
|
78
85
|
subject.with_running_user_defined_pipelines {|pipelines| pipelines.keys }
|
79
86
|
end.to eq([:main])
|
@@ -82,7 +89,6 @@ describe LogStash::Agent do
|
|
82
89
|
|
83
90
|
describe "#running_user_defined_pipelines?" do
|
84
91
|
it "returns true" do
|
85
|
-
start_agent(subject)
|
86
92
|
wait_for do
|
87
93
|
subject.running_user_defined_pipelines?
|
88
94
|
end.to be_truthy
|
@@ -102,14 +108,19 @@ describe LogStash::Agent do
|
|
102
108
|
context "and successfully load the config" do
|
103
109
|
let(:agent_settings) { mock_settings("config.reload.automatic" => false) }
|
104
110
|
|
105
|
-
|
106
|
-
agent_task = start_agent(subject)
|
111
|
+
before(:each) do
|
112
|
+
@agent_task = start_agent(subject)
|
113
|
+
end
|
107
114
|
|
115
|
+
after(:each) do
|
116
|
+
@agent_task.stop!
|
117
|
+
end
|
118
|
+
|
119
|
+
it "converge only once" do
|
108
120
|
expect(source_loader.fetch_count).to eq(1)
|
109
121
|
expect(subject).to have_running_pipeline?(pipeline_config)
|
110
122
|
|
111
123
|
subject.shutdown
|
112
|
-
agent_task.stop!
|
113
124
|
end
|
114
125
|
end
|
115
126
|
|
@@ -137,11 +148,16 @@ describe LogStash::Agent do
|
|
137
148
|
"config.reload.interval" => interval
|
138
149
|
)
|
139
150
|
end
|
151
|
+
before(:each) do
|
152
|
+
@agent_task = start_agent(subject)
|
153
|
+
end
|
154
|
+
|
155
|
+
after(:each) do
|
156
|
+
@agent_task.stop!
|
157
|
+
end
|
140
158
|
|
141
159
|
context "and successfully load the config" do
|
142
160
|
it "converges periodically the pipelines from the configs source" do
|
143
|
-
agent_task = start_agent(subject)
|
144
|
-
|
145
161
|
sleep(2) # let the interval reload a few times
|
146
162
|
expect(subject).to have_running_pipeline?(pipeline_config)
|
147
163
|
|
@@ -152,7 +168,6 @@ describe LogStash::Agent do
|
|
152
168
|
end
|
153
169
|
|
154
170
|
subject.shutdown
|
155
|
-
agent_task.stop!
|
156
171
|
end
|
157
172
|
end
|
158
173
|
|
@@ -162,14 +177,12 @@ describe LogStash::Agent do
|
|
162
177
|
end
|
163
178
|
|
164
179
|
it "it will keep trying to converge" do
|
165
|
-
agent_task = start_agent(subject)
|
166
180
|
|
167
181
|
sleep(agent_settings.get("config.reload.interval") / 1_000_000_000.0 * 20) # let the interval reload a few times
|
168
182
|
expect(subject.pipelines_count).to eq(0)
|
169
183
|
expect(source_loader.fetch_count).to be > 1
|
170
184
|
|
171
185
|
subject.shutdown
|
172
|
-
agent_task.stop!
|
173
186
|
end
|
174
187
|
end
|
175
188
|
end
|
data/spec/logstash/agent_spec.rb
CHANGED
@@ -26,6 +26,7 @@ describe LogStash::Agent do
|
|
26
26
|
sl
|
27
27
|
end
|
28
28
|
let(:logger) { double("logger") }
|
29
|
+
let(:timeout) {120} #seconds
|
29
30
|
|
30
31
|
subject { LogStash::Agent.new(agent_settings, default_source_loader) }
|
31
32
|
|
@@ -33,7 +34,7 @@ describe LogStash::Agent do
|
|
33
34
|
# This MUST run first, before `subject` is invoked to ensure clean state
|
34
35
|
clear_data_dir
|
35
36
|
|
36
|
-
File.open(config_file, "w") { |f| f.puts
|
37
|
+
File.open(config_file, "w") { |f| f.puts(config_file_txt) }
|
37
38
|
|
38
39
|
agent_args.each do |key, value|
|
39
40
|
agent_settings.set(key, value)
|
@@ -50,8 +51,9 @@ describe LogStash::Agent do
|
|
50
51
|
after :each do
|
51
52
|
subject.shutdown
|
52
53
|
LogStash::SETTINGS.reset
|
53
|
-
|
54
|
-
|
54
|
+
|
55
|
+
FileUtils.rm(config_file)
|
56
|
+
FileUtils.rm_rf(subject.id_path)
|
55
57
|
end
|
56
58
|
|
57
59
|
it "fallback to hostname when no name is provided" do
|
@@ -314,8 +316,10 @@ describe LogStash::Agent do
|
|
314
316
|
context "metrics after config reloading" do
|
315
317
|
|
316
318
|
let(:initial_generator_threshold) { 1000 }
|
317
|
-
let(:
|
318
|
-
let(:
|
319
|
+
let(:original_config_output) { Stud::Temporary.pathname }
|
320
|
+
let(:new_config_output) { Stud::Temporary.pathname }
|
321
|
+
|
322
|
+
let(:config_file_txt) { "input { generator { count => #{initial_generator_threshold*2} } } output { file { path => '#{original_config_output}'} }" }
|
319
323
|
|
320
324
|
let(:agent_args) do
|
321
325
|
{
|
@@ -326,14 +330,25 @@ describe LogStash::Agent do
|
|
326
330
|
|
327
331
|
subject { described_class.new(agent_settings, default_source_loader) }
|
328
332
|
|
333
|
+
let(:agent_thread) do
|
334
|
+
# subject has to be called for the first time outside the thread because it could create a race condition
|
335
|
+
# with subsequent subject calls
|
336
|
+
s = subject
|
337
|
+
Thread.new { s.execute }
|
338
|
+
end
|
339
|
+
|
329
340
|
before(:each) do
|
330
341
|
@abort_on_exception = Thread.abort_on_exception
|
331
342
|
Thread.abort_on_exception = true
|
332
343
|
|
333
|
-
|
344
|
+
agent_thread
|
334
345
|
|
335
346
|
# wait for some events to reach the dummy_output
|
336
|
-
|
347
|
+
Timeout.timeout(timeout) do
|
348
|
+
# wait for file existence otherwise it will raise exception on Windows
|
349
|
+
sleep(0.1) until ::File.exist?(original_config_output)
|
350
|
+
sleep(0.1) until IO.readlines(original_config_output).size > initial_generator_threshold
|
351
|
+
end
|
337
352
|
|
338
353
|
# write new config
|
339
354
|
File.open(config_file, "w") { |f| f.write(new_config) }
|
@@ -341,10 +356,14 @@ describe LogStash::Agent do
|
|
341
356
|
|
342
357
|
after :each do
|
343
358
|
begin
|
359
|
+
Stud.stop!(agent_thread) rescue nil # it may be dead already
|
360
|
+
agent_thread.join
|
344
361
|
subject.shutdown
|
345
|
-
|
346
|
-
|
347
|
-
File.
|
362
|
+
|
363
|
+
FileUtils.rm(original_config_output)
|
364
|
+
FileUtils.rm(new_config_output) if File.exist?(new_config_output)
|
365
|
+
rescue
|
366
|
+
#don't care about errors here.
|
348
367
|
ensure
|
349
368
|
Thread.abort_on_exception = @abort_on_exception
|
350
369
|
end
|
@@ -352,19 +371,20 @@ describe LogStash::Agent do
|
|
352
371
|
|
353
372
|
context "when reloading a good config" do
|
354
373
|
let(:new_config_generator_counter) { 500 }
|
355
|
-
let(:
|
356
|
-
let(:new_config) { "input { generator { count => #{new_config_generator_counter} } } output { file { path => '#{new_file}'} }" }
|
374
|
+
let(:new_config) { "input { generator { count => #{new_config_generator_counter} } } output { file { path => '#{new_config_output}'} }" }
|
357
375
|
|
358
376
|
before :each do
|
359
377
|
subject.converge_state_and_update
|
360
|
-
|
378
|
+
Timeout.timeout(timeout) do
|
379
|
+
# wait for file existence otherwise it will raise exception on Windows
|
380
|
+
sleep(0.1) until ::File.exist?(new_config_output)
|
381
|
+
sleep(0.1) while ::File.read(new_config_output).chomp.empty?
|
382
|
+
end
|
361
383
|
# ensure the converge_state_and_update method has updated metrics by
|
362
384
|
# invoking the mutex
|
363
385
|
subject.running_pipelines?
|
364
386
|
end
|
365
387
|
|
366
|
-
after(:each) { File.unlink(new_file) }
|
367
|
-
|
368
388
|
it "resets the pipeline metric collector" do
|
369
389
|
snapshot = subject.metric.collector.snapshot_metric
|
370
390
|
value = snapshot.metric_store.get_with_path("/stats/pipelines")[:stats][:pipelines][:main][:events][:in].value
|
@@ -69,7 +69,7 @@ describe LogStash::Api::Modules::NodeStats do
|
|
69
69
|
"cpu"=>{
|
70
70
|
"total_in_millis"=>Numeric,
|
71
71
|
"percent"=>Numeric,
|
72
|
-
|
72
|
+
# load_average is not supported on Windows, set it below
|
73
73
|
}
|
74
74
|
},
|
75
75
|
"pipelines" => {
|
@@ -89,5 +89,9 @@ describe LogStash::Api::Modules::NodeStats do
|
|
89
89
|
}
|
90
90
|
}
|
91
91
|
|
92
|
+
unless LogStash::Environment.windows?
|
93
|
+
root_structure["process"]["cpu"]["load_average"] = { "1m" => Numeric }
|
94
|
+
end
|
95
|
+
|
92
96
|
test_api_and_resources(root_structure)
|
93
97
|
end
|
@@ -193,6 +193,35 @@ describe LogStash::Compiler do
|
|
193
193
|
expect(c_plugin).to ir_eql(j.iPlugin(INPUT, "generator", expected_plugin_args))
|
194
194
|
end
|
195
195
|
end
|
196
|
+
|
197
|
+
describe "a filter plugin that repeats a Hash directive" do
|
198
|
+
let(:source) { "input { } filter { #{plugin_source} } output { } " }
|
199
|
+
subject(:c_plugin) { compiled[:filter] }
|
200
|
+
|
201
|
+
let(:plugin_source) do
|
202
|
+
%q[
|
203
|
+
grok {
|
204
|
+
match => { "message" => "%{WORD:word}" }
|
205
|
+
match => { "examplefield" => "%{NUMBER:num}" }
|
206
|
+
break_on_match => false
|
207
|
+
}
|
208
|
+
]
|
209
|
+
end
|
210
|
+
|
211
|
+
let(:expected_plugin_args) do
|
212
|
+
{
|
213
|
+
"match" => {
|
214
|
+
"message" => "%{WORD:word}",
|
215
|
+
"examplefield" => "%{NUMBER:num}"
|
216
|
+
},
|
217
|
+
"break_on_match" => "false"
|
218
|
+
}
|
219
|
+
end
|
220
|
+
|
221
|
+
it "should merge the contents of the individual directives" do
|
222
|
+
expect(c_plugin).to ir_eql(j.iPlugin(FILTER, "grok", expected_plugin_args))
|
223
|
+
end
|
224
|
+
end
|
196
225
|
end
|
197
226
|
|
198
227
|
context "inputs" do
|
@@ -79,7 +79,7 @@ describe LogStash::Config::Source::Local::ConfigPathLoader do
|
|
79
79
|
|
80
80
|
parts.each do |part|
|
81
81
|
basename = ::File.basename(part.id)
|
82
|
-
file_path = ::File.join(directory, basename)
|
82
|
+
file_path = ::File.expand_path(::File.join(directory, basename))
|
83
83
|
content = files[basename]
|
84
84
|
expect(part).to be_a_source_with_metadata("file", file_path, content)
|
85
85
|
end
|
@@ -99,7 +99,8 @@ describe LogStash::Config::Source::Local::ConfigPathLoader do
|
|
99
99
|
end
|
100
100
|
|
101
101
|
it "raises an exception" do
|
102
|
-
|
102
|
+
# check against base name because on Windows long paths are shrinked in the exception message
|
103
|
+
expect { subject.read(file_path) }.to raise_error LogStash::ConfigLoadingError, /.+#{::File.basename(file_path)}/
|
103
104
|
end
|
104
105
|
end
|
105
106
|
|
data/spec/logstash/event_spec.rb
CHANGED
@@ -352,4 +352,61 @@ describe LogStash::Event do
|
|
352
352
|
expect { subject.baz() }.to raise_error(NoMethodError, /undefined method `baz' for/)
|
353
353
|
end
|
354
354
|
end
|
355
|
+
|
356
|
+
describe "#clone" do
|
357
|
+
let(:fieldref) { "[@metadata][fancy]" }
|
358
|
+
let(:event1) { LogStash::Event.new("hello" => "world", "@metadata" => { "fancy" => "pants" }) }
|
359
|
+
let(:event2) { LogStash::Event.new("hello" => "world", "@metadata" => { "fancy" => {"fancy2" => "pants2"} }) }
|
360
|
+
let(:event3) { LogStash::Event.new("hello" => "world", "@metadata" => { "fancy" => {"fancy2" => {"fancy3" => "pants2"}} }) }
|
361
|
+
let(:event4) { LogStash::Event.new("hello" => "world", "@metadata" => { "fancy" => {"fancy2" => ["pants1", "pants2"]} }) }
|
362
|
+
let(:event5) { LogStash::Event.new("hello" => "world", "@metadata" => { "fancy" => "pants", "smarty" => "pants2" }) }
|
363
|
+
|
364
|
+
it "should clone metadata fields" do
|
365
|
+
cloned = event1.clone
|
366
|
+
expect(cloned.get(fieldref)).to eq("pants")
|
367
|
+
expect(cloned.to_hash_with_metadata).to include("@metadata")
|
368
|
+
end
|
369
|
+
|
370
|
+
it "should clone metadata fields with nested json" do
|
371
|
+
cloned = event2.clone
|
372
|
+
expect(cloned.get(fieldref)).to eq({"fancy2" => "pants2"})
|
373
|
+
expect(cloned.get("hello")).to eq("world")
|
374
|
+
expect(cloned.to_hash).not_to include("@metadata")
|
375
|
+
expect(cloned.to_hash_with_metadata).to include("@metadata")
|
376
|
+
end
|
377
|
+
|
378
|
+
it "should clone metadata fields with 2-level nested json" do
|
379
|
+
cloned = event3.clone
|
380
|
+
expect(cloned.get(fieldref)).to eq({"fancy2" => {"fancy3" => "pants2"}})
|
381
|
+
expect(cloned.to_hash).not_to include("@metadata")
|
382
|
+
expect(cloned.to_hash_with_metadata).to include("@metadata")
|
383
|
+
end
|
384
|
+
|
385
|
+
it "should clone metadata fields with nested json and array value" do
|
386
|
+
cloned = event4.clone
|
387
|
+
expect(cloned.get(fieldref)).to eq({"fancy2" => ["pants1", "pants2"]})
|
388
|
+
expect(cloned.to_hash_with_metadata).to include("@metadata")
|
389
|
+
end
|
390
|
+
|
391
|
+
it "should clone metadata fields with multiple keys" do
|
392
|
+
cloned = event5.clone
|
393
|
+
expect(cloned.get(fieldref)).to eq("pants")
|
394
|
+
expect(cloned.get("[@metadata][smarty]")).to eq("pants2")
|
395
|
+
expect(cloned.to_hash_with_metadata).to include("@metadata")
|
396
|
+
end
|
397
|
+
|
398
|
+
it "mutating cloned event should not affect the original event" do
|
399
|
+
cloned = event1.clone
|
400
|
+
cloned.set("hello", "foobar")
|
401
|
+
expect(cloned.get("hello")).to eq("foobar")
|
402
|
+
expect(event1.get("hello")).to eq("world")
|
403
|
+
end
|
404
|
+
|
405
|
+
it "mutating cloned event's metadata should not affect the original event metadata" do
|
406
|
+
cloned = event1.clone
|
407
|
+
cloned.set("[@metadata][fancy]", "foobar")
|
408
|
+
expect(cloned.get("[@metadata][fancy]")).to eq("foobar")
|
409
|
+
expect(event1.get("[@metadata][fancy]")).to eq("pants")
|
410
|
+
end
|
411
|
+
end
|
355
412
|
end
|