logstash-core 5.0.2-java → 5.1.1.1-java
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.
- checksums.yaml +4 -4
- data/gemspec_jars.rb +9 -0
- data/lib/logstash-core/logstash-core.jar +0 -0
- data/lib/logstash-core/logstash-core.rb +22 -0
- data/lib/logstash-core/version.rb +1 -1
- data/lib/logstash-core_jars.rb +20 -0
- data/lib/logstash/agent.rb +65 -14
- data/lib/logstash/api/commands/default_metadata.rb +2 -1
- data/lib/logstash/api/commands/stats.rb +3 -2
- data/lib/logstash/config/file.rb +0 -1
- data/lib/logstash/config/loader.rb +1 -0
- data/lib/logstash/config/mixin.rb +2 -6
- data/lib/logstash/environment.rb +25 -2
- data/lib/logstash/event_dispatcher.rb +40 -0
- data/lib/logstash/filter_delegator.rb +1 -1
- data/lib/logstash/filters/base.rb +10 -2
- data/lib/logstash/instrument/metric_store.rb +0 -1
- data/lib/logstash/instrument/metric_type/base.rb +0 -1
- data/lib/logstash/instrument/namespaced_null_metric.rb +54 -0
- data/lib/logstash/instrument/null_metric.rb +55 -46
- data/lib/logstash/instrument/periodic_poller/jvm.rb +26 -3
- data/lib/logstash/instrument/periodic_poller/load_average.rb +47 -0
- data/lib/logstash/instrument/snapshot.rb +0 -1
- data/lib/logstash/java_integration.rb +0 -1
- data/lib/logstash/logging/logger.rb +37 -4
- data/lib/logstash/outputs/base.rb +1 -1
- data/lib/logstash/patches.rb +1 -0
- data/lib/logstash/patches/exception_to_json.rb +5 -0
- data/lib/logstash/pipeline.rb +50 -17
- data/lib/logstash/plugin.rb +14 -48
- data/lib/logstash/plugins/hooks_registry.rb +57 -0
- data/lib/logstash/plugins/registry.rb +208 -45
- data/lib/logstash/runner.rb +10 -5
- data/lib/logstash/settings.rb +101 -9
- data/lib/logstash/universal_plugin.rb +13 -0
- data/lib/logstash/util/byte_value.rb +60 -0
- data/lib/logstash/util/loggable.rb +14 -2
- data/lib/logstash/util/safe_uri.rb +1 -0
- data/lib/logstash/util/time_value.rb +70 -0
- data/lib/logstash/util/wrapped_acked_queue.rb +347 -0
- data/lib/logstash/util/wrapped_synchronous_queue.rb +17 -33
- data/lib/logstash/version.rb +1 -1
- data/locales/en.yml +1 -1
- data/logstash-core.gemspec +13 -18
- data/spec/api/lib/api/node_stats_spec.rb +3 -1
- data/spec/api/lib/api/support/resource_dsl_methods.rb +14 -6
- data/spec/api/spec_helper.rb +1 -0
- data/spec/conditionals_spec.rb +3 -2
- data/spec/logstash/agent_spec.rb +142 -62
- data/spec/logstash/environment_spec.rb +38 -0
- data/spec/logstash/event_dispatcher_spec.rb +76 -0
- data/spec/logstash/filter_delegator_spec.rb +2 -1
- data/spec/logstash/instrument/namespaced_null_metric_spec.rb +33 -0
- data/spec/logstash/instrument/null_metric_spec.rb +9 -5
- data/spec/logstash/instrument/periodic_poller/jvm_spec.rb +40 -0
- data/spec/logstash/instrument/periodic_poller/load_average_spec.rb +91 -0
- data/spec/logstash/output_delegator_spec.rb +2 -1
- data/spec/logstash/patches_spec.rb +15 -4
- data/spec/logstash/pipeline_pq_file_spec.rb +131 -0
- data/spec/logstash/pipeline_spec.rb +21 -17
- data/spec/logstash/plugin_spec.rb +4 -16
- data/spec/logstash/plugins/hooks_registry_spec.rb +60 -0
- data/spec/logstash/plugins/registry_spec.rb +22 -14
- data/spec/logstash/settings/bytes_spec.rb +53 -0
- data/spec/logstash/settings/time_value_spec.rb +31 -0
- data/spec/logstash/settings/writable_directory_spec.rb +125 -0
- data/spec/logstash/settings_spec.rb +39 -0
- data/spec/logstash/util/byte_value_spec.rb +33 -0
- data/spec/logstash/util/time_value_spec.rb +59 -0
- data/spec/logstash/util/wrapped_synchronous_queue_spec.rb +2 -2
- data/spec/logstash/webserver_spec.rb +4 -7
- data/spec/support/helpers.rb +8 -0
- data/spec/support/mocks_classes.rb +61 -31
- metadata +73 -20
- data/lib/jars.rb +0 -7
- data/lib/logstash/config/registry.rb +0 -13
- data/lib/logstash/inputs/metrics.rb +0 -47
- data/spec/logstash/inputs/metrics_spec.rb +0 -51
- data/vendor/jars/com/fasterxml/jackson/core/jackson-core/2.7.4/jackson-core-2.7.4.jar +0 -0
- data/vendor/jars/com/fasterxml/jackson/core/jackson-databind/2.7.4/jackson-databind-2.7.4.jar +0 -0
- data/vendor/jars/org/apache/logging/log4j/log4j-1.2-api/2.6.2/log4j-1.2-api-2.6.2.jar +0 -0
- data/vendor/jars/org/apache/logging/log4j/log4j-api/2.6.2/log4j-api-2.6.2.jar +0 -0
- data/vendor/jars/org/apache/logging/log4j/log4j-core/2.6.2/log4j-core-2.6.2.jar +0 -0
- data/vendor/jars/org/logstash/logstash-core/5.0.2/logstash-core-5.0.2.jar +0 -0
|
@@ -104,15 +104,15 @@ describe LogStash::Pipeline do
|
|
|
104
104
|
describe "event cancellation" do
|
|
105
105
|
# test harness for https://github.com/elastic/logstash/issues/6055
|
|
106
106
|
|
|
107
|
-
let(:output) { DummyOutputWithEventsArray.new }
|
|
107
|
+
let(:output) { LogStash::Outputs::DummyOutputWithEventsArray.new }
|
|
108
108
|
|
|
109
109
|
before do
|
|
110
110
|
allow(LogStash::Plugin).to receive(:lookup).with("input", "generator").and_return(LogStash::Inputs::Generator)
|
|
111
|
-
allow(LogStash::Plugin).to receive(:lookup).with("output", "dummyoutputwitheventsarray").and_return(DummyOutputWithEventsArray)
|
|
111
|
+
allow(LogStash::Plugin).to receive(:lookup).with("output", "dummyoutputwitheventsarray").and_return(LogStash::Outputs::DummyOutputWithEventsArray)
|
|
112
112
|
allow(LogStash::Plugin).to receive(:lookup).with("filter", "drop").and_call_original
|
|
113
113
|
allow(LogStash::Plugin).to receive(:lookup).with("filter", "mutate").and_call_original
|
|
114
114
|
allow(LogStash::Plugin).to receive(:lookup).with("codec", "plain").and_call_original
|
|
115
|
-
allow(DummyOutputWithEventsArray).to receive(:new).with(any_args).and_return(output)
|
|
115
|
+
allow(LogStash::Outputs::DummyOutputWithEventsArray).to receive(:new).with(any_args).and_return(output)
|
|
116
116
|
end
|
|
117
117
|
|
|
118
118
|
let(:config) do
|
|
@@ -447,6 +447,13 @@ describe LogStash::Pipeline do
|
|
|
447
447
|
allow(settings).to receive(:get_value).with("pipeline.id").and_return("main")
|
|
448
448
|
allow(settings).to receive(:get_value).with("metric.collect").and_return(false)
|
|
449
449
|
allow(settings).to receive(:get_value).with("config.debug").and_return(false)
|
|
450
|
+
allow(settings).to receive(:get).with("queue.type").and_return("memory")
|
|
451
|
+
allow(settings).to receive(:get).with("queue.page_capacity").and_return(1024 * 1024)
|
|
452
|
+
allow(settings).to receive(:get).with("queue.max_events").and_return(250)
|
|
453
|
+
allow(settings).to receive(:get).with("queue.max_bytes").and_return(1024 * 1024 * 1024)
|
|
454
|
+
allow(settings).to receive(:get).with("queue.checkpoint.acks").and_return(1024)
|
|
455
|
+
allow(settings).to receive(:get).with("queue.checkpoint.writes").and_return(1024)
|
|
456
|
+
allow(settings).to receive(:get).with("queue.checkpoint.interval").and_return(1000)
|
|
450
457
|
|
|
451
458
|
pipeline = LogStash::Pipeline.new(config, settings)
|
|
452
459
|
expect(pipeline.metric).to be_kind_of(LogStash::Instrument::NullMetric)
|
|
@@ -509,7 +516,7 @@ describe LogStash::Pipeline do
|
|
|
509
516
|
pipeline = LogStash::Pipeline.new(config, pipeline_settings_obj)
|
|
510
517
|
Thread.new { pipeline.run }
|
|
511
518
|
sleep 0.1 while !pipeline.ready?
|
|
512
|
-
wait(
|
|
519
|
+
wait(3).for do
|
|
513
520
|
# give us a bit of time to flush the events
|
|
514
521
|
output.events.empty?
|
|
515
522
|
end.to be_falsey
|
|
@@ -549,10 +556,11 @@ describe LogStash::Pipeline do
|
|
|
549
556
|
end
|
|
550
557
|
|
|
551
558
|
context "#started_at" do
|
|
559
|
+
# use a run limiting count to shutdown the pipeline automatically
|
|
552
560
|
let(:config) do
|
|
553
561
|
<<-EOS
|
|
554
562
|
input {
|
|
555
|
-
generator {}
|
|
563
|
+
generator { count => 10 }
|
|
556
564
|
}
|
|
557
565
|
EOS
|
|
558
566
|
end
|
|
@@ -564,8 +572,7 @@ describe LogStash::Pipeline do
|
|
|
564
572
|
end
|
|
565
573
|
|
|
566
574
|
it "return when the pipeline started working" do
|
|
567
|
-
|
|
568
|
-
sleep(0.1)
|
|
575
|
+
subject.run
|
|
569
576
|
expect(subject.started_at).to be < Time.now
|
|
570
577
|
subject.shutdown
|
|
571
578
|
end
|
|
@@ -604,7 +611,7 @@ describe LogStash::Pipeline do
|
|
|
604
611
|
|
|
605
612
|
let(:pipeline_settings) { { "pipeline.id" => pipeline_id } }
|
|
606
613
|
let(:pipeline_id) { "main" }
|
|
607
|
-
let(:number_of_events) {
|
|
614
|
+
let(:number_of_events) { 420 }
|
|
608
615
|
let(:multiline_id) { "my-multiline" }
|
|
609
616
|
let(:multiline_id_other) { "my-multiline_other" }
|
|
610
617
|
let(:dummy_output_id) { "my-dummyoutput" }
|
|
@@ -648,13 +655,10 @@ describe LogStash::Pipeline do
|
|
|
648
655
|
|
|
649
656
|
Thread.new { subject.run }
|
|
650
657
|
# make sure we have received all the generated events
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
sleep 0.25
|
|
656
|
-
raise "Waited too long" if times > 4
|
|
657
|
-
end
|
|
658
|
+
wait(3).for do
|
|
659
|
+
# give us a bit of time to flush the events
|
|
660
|
+
dummyoutput.events.size < number_of_events
|
|
661
|
+
end.to be_falsey
|
|
658
662
|
end
|
|
659
663
|
|
|
660
664
|
after :each do
|
|
@@ -685,7 +689,7 @@ describe LogStash::Pipeline do
|
|
|
685
689
|
it "populates the filter metrics" do
|
|
686
690
|
[multiline_id, multiline_id_other].map(&:to_sym).each do |id|
|
|
687
691
|
[:in, :out].each do |metric_key|
|
|
688
|
-
plugin_name =
|
|
692
|
+
plugin_name = id.to_sym
|
|
689
693
|
expect(collected_metric[:stats][:pipelines][:main][:plugins][:filters][plugin_name][:events][metric_key].value).to eq(number_of_events)
|
|
690
694
|
end
|
|
691
695
|
end
|
|
@@ -703,7 +707,7 @@ describe LogStash::Pipeline do
|
|
|
703
707
|
|
|
704
708
|
it "populates the name of the filter plugin" do
|
|
705
709
|
[multiline_id, multiline_id_other].map(&:to_sym).each do |id|
|
|
706
|
-
plugin_name =
|
|
710
|
+
plugin_name = id.to_sym
|
|
707
711
|
expect(collected_metric[:stats][:pipelines][:main][:plugins][:filters][plugin_name][:name].value).to eq(LogStash::Filters::Multiline.config_name)
|
|
708
712
|
end
|
|
709
713
|
end
|
|
@@ -31,20 +31,8 @@ describe LogStash::Plugin do
|
|
|
31
31
|
class LogStash::Filters::LadyGaga < LogStash::Filters::Base
|
|
32
32
|
config_name "lady_gaga"
|
|
33
33
|
end
|
|
34
|
-
expect(LogStash::Plugin.lookup("filter", "lady_gaga")).to eq(LogStash::Filters::LadyGaga)
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
describe "plugin signup in the registry" do
|
|
38
|
-
|
|
39
|
-
let(:registry) { LogStash::Registry.instance }
|
|
40
34
|
|
|
41
|
-
|
|
42
|
-
class LogStash::Filters::MyPlugin < LogStash::Filters::Base
|
|
43
|
-
config_name "my_plugin"
|
|
44
|
-
end
|
|
45
|
-
path = "logstash/filters/my_plugin"
|
|
46
|
-
expect(registry.registered?(path)).to eq(true)
|
|
47
|
-
end
|
|
35
|
+
expect(LogStash::Plugin.lookup("filter", "lady_gaga")).to eq(LogStash::Filters::LadyGaga)
|
|
48
36
|
end
|
|
49
37
|
|
|
50
38
|
describe "#inspect" do
|
|
@@ -296,7 +284,7 @@ describe LogStash::Plugin do
|
|
|
296
284
|
end
|
|
297
285
|
|
|
298
286
|
it "should use a `NullMetric`" do
|
|
299
|
-
expect(subject.metric).to be_kind_of(LogStash::Instrument::
|
|
287
|
+
expect(subject.metric).to be_kind_of(LogStash::Instrument::NamespacedNullMetric)
|
|
300
288
|
end
|
|
301
289
|
end
|
|
302
290
|
|
|
@@ -308,7 +296,7 @@ describe LogStash::Plugin do
|
|
|
308
296
|
end
|
|
309
297
|
|
|
310
298
|
it "should use a `NullMetric`" do
|
|
311
|
-
expect(subject.metric).to be_kind_of(LogStash::Instrument::
|
|
299
|
+
expect(subject.metric).to be_kind_of(LogStash::Instrument::NamespacedNullMetric)
|
|
312
300
|
end
|
|
313
301
|
end
|
|
314
302
|
end
|
|
@@ -338,7 +326,7 @@ describe LogStash::Plugin do
|
|
|
338
326
|
end
|
|
339
327
|
|
|
340
328
|
it "should use a `NullMetric`" do
|
|
341
|
-
expect(subject.metric).to be_kind_of(LogStash::Instrument::
|
|
329
|
+
expect(subject.metric).to be_kind_of(LogStash::Instrument::NamespacedNullMetric)
|
|
342
330
|
end
|
|
343
331
|
end
|
|
344
332
|
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require "logstash/event_dispatcher"
|
|
3
|
+
require "logstash/plugins/hooks_registry"
|
|
4
|
+
|
|
5
|
+
describe LogStash::Plugins::HooksRegistry do
|
|
6
|
+
class DummyEmitter
|
|
7
|
+
attr_reader :dispatcher
|
|
8
|
+
|
|
9
|
+
def initialize
|
|
10
|
+
@dispatcher = LogStash::EventDispatcher.new(self)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def do_work
|
|
14
|
+
dispatcher.fire(:do_work)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
class DummyListener
|
|
19
|
+
def initialize
|
|
20
|
+
@work = false
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def do_work(emitter = nil)
|
|
24
|
+
@work = true
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def work?
|
|
28
|
+
@work
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
subject { described_class.new }
|
|
33
|
+
|
|
34
|
+
let(:emitter) { DummyEmitter.new }
|
|
35
|
+
let(:listener) { DummyListener.new }
|
|
36
|
+
|
|
37
|
+
it "allow to register an emitter" do
|
|
38
|
+
expect { subject.register_emitter(emitter.class, emitter.dispatcher) }.to change { subject.emmitters_count }.by(1)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "allow to remove an emitter" do
|
|
42
|
+
subject.register_emitter(emitter.class, emitter.dispatcher)
|
|
43
|
+
expect { subject.remove_emitter(emitter.class)}.to change { subject.emmitters_count }.by(-1)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "allow to register hooks to emitters" do
|
|
47
|
+
expect { subject.register_hooks(emitter.class, listener) }.to change { subject.hooks_count }.by(1)
|
|
48
|
+
expect { subject.register_hooks(emitter.class, listener) }.to change { subject.hooks_count(emitter.class) }.by(1)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "link the emitter class to the listener" do
|
|
52
|
+
subject.register_emitter(emitter.class, emitter.dispatcher)
|
|
53
|
+
subject.register_hooks(emitter.class, listener)
|
|
54
|
+
|
|
55
|
+
expect(listener.work?).to be_falsey
|
|
56
|
+
emitter.do_work
|
|
57
|
+
|
|
58
|
+
expect(listener.work?).to be_truthy
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -8,15 +8,19 @@ class LogStash::Inputs::Dummy < LogStash::Inputs::Base
|
|
|
8
8
|
config_name "dummy"
|
|
9
9
|
|
|
10
10
|
def register; end
|
|
11
|
-
|
|
12
11
|
end
|
|
13
12
|
|
|
14
|
-
describe LogStash::Registry do
|
|
15
13
|
|
|
16
|
-
|
|
14
|
+
class LogStash::Inputs::NewPlugin < LogStash::Inputs::Base
|
|
15
|
+
config_name "new_plugin"
|
|
17
16
|
|
|
18
|
-
|
|
17
|
+
def register; end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
describe LogStash::Plugins::Registry do
|
|
21
|
+
let(:registry) { described_class.new }
|
|
19
22
|
|
|
23
|
+
context "when loading installed plugins" do
|
|
20
24
|
let(:plugin) { double("plugin") }
|
|
21
25
|
|
|
22
26
|
it "should return the expected class" do
|
|
@@ -25,18 +29,13 @@ describe LogStash::Registry do
|
|
|
25
29
|
end
|
|
26
30
|
|
|
27
31
|
it "should raise an error if can not find the plugin class" do
|
|
28
|
-
expect
|
|
29
|
-
expect(plugin).to receive(:path).and_return("logstash/input/elastic").twice
|
|
30
|
-
expect(plugin).to receive(:installed?).and_return(true)
|
|
31
|
-
expect { registry.lookup("input", "elastic") }.to raise_error(LoadError)
|
|
32
|
+
expect { registry.lookup("input", "do-not-exist-elastic") }.to raise_error(LoadError)
|
|
32
33
|
end
|
|
33
34
|
|
|
34
35
|
it "should load from registry is already load" do
|
|
35
|
-
registry.
|
|
36
|
-
expect(
|
|
37
|
-
registry.lookup("input", "
|
|
38
|
-
internal_registry = registry.instance_variable_get("@registry")
|
|
39
|
-
expect(internal_registry).to include("logstash/inputs/stdin" => LogStash::Inputs::Stdin)
|
|
36
|
+
expect(registry.exists?(:input, "stdin")).to be_falsey
|
|
37
|
+
expect { registry.lookup("input", "new_plugin") }.to change { registry.size }.by(1)
|
|
38
|
+
expect { registry.lookup("input", "new_plugin") }.not_to change { registry.size }
|
|
40
39
|
end
|
|
41
40
|
end
|
|
42
41
|
|
|
@@ -53,5 +52,14 @@ describe LogStash::Registry do
|
|
|
53
52
|
end
|
|
54
53
|
end
|
|
55
54
|
|
|
56
|
-
|
|
55
|
+
context "when loading plugin manually configured" do
|
|
56
|
+
it "should return the plugin" do
|
|
57
|
+
class SimplePlugin
|
|
58
|
+
end
|
|
57
59
|
|
|
60
|
+
expect { registry.lookup("filter", "simple_plugin") }.to raise_error(LoadError)
|
|
61
|
+
registry.add(:filter, "simple_plugin", SimplePlugin)
|
|
62
|
+
expect(registry.lookup("filter", "simple_plugin")).to eq(SimplePlugin)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require "spec_helper"
|
|
3
|
+
require "logstash/settings"
|
|
4
|
+
|
|
5
|
+
describe LogStash::Setting::Bytes do
|
|
6
|
+
let(:multipliers) do
|
|
7
|
+
{
|
|
8
|
+
"b" => 1,
|
|
9
|
+
"kb" => 1 << 10,
|
|
10
|
+
"mb" => 1 << 20,
|
|
11
|
+
"gb" => 1 << 30,
|
|
12
|
+
"tb" => 1 << 40,
|
|
13
|
+
"pb" => 1 << 50,
|
|
14
|
+
}
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
let(:number) { Flores::Random.number(0..1000) }
|
|
18
|
+
let(:unit) { Flores::Random.item(multipliers.keys) }
|
|
19
|
+
let(:default) { "0b" }
|
|
20
|
+
|
|
21
|
+
subject { described_class.new("a byte value", default, false) }
|
|
22
|
+
|
|
23
|
+
describe "#set" do
|
|
24
|
+
|
|
25
|
+
# Hard-coded test just to make sure at least one known case is working
|
|
26
|
+
context "when given '10mb'" do
|
|
27
|
+
it "returns 10485760" do
|
|
28
|
+
expect(subject.set("10mb")).to be == 10485760
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
context "when given a string" do
|
|
33
|
+
context "which is a valid byte unit" do
|
|
34
|
+
let(:text) { "#{number}#{unit}" }
|
|
35
|
+
|
|
36
|
+
before { subject.set(text) }
|
|
37
|
+
|
|
38
|
+
it "should coerce it to a Fixnum" do
|
|
39
|
+
expect(subject.value).to be_a(Fixnum)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
context "which is not a valid byte unit" do
|
|
44
|
+
values = [ "hello world", "1234", "", "-__-" ]
|
|
45
|
+
values.each do |value|
|
|
46
|
+
it "should fail" do
|
|
47
|
+
expect { subject.set(value) }.to raise_error
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require "spec_helper"
|
|
3
|
+
require "logstash/settings"
|
|
4
|
+
|
|
5
|
+
describe LogStash::Setting::TimeValue do
|
|
6
|
+
subject { described_class.new("option", "-1") }
|
|
7
|
+
describe "#set" do
|
|
8
|
+
it "should coerce the default correctly" do
|
|
9
|
+
expect(subject.value).to eq(LogStash::Util::TimeValue.new(-1, :nanosecond).to_nanos)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
context "when a value is given outside of possible_values" do
|
|
13
|
+
it "should raise an ArgumentError" do
|
|
14
|
+
expect { subject.set("invalid") }.to raise_error(ArgumentError)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
context "when a value is given as a time value" do
|
|
18
|
+
it "should set the value" do
|
|
19
|
+
subject.set("18m")
|
|
20
|
+
expect(subject.value).to eq(LogStash::Util::TimeValue.new(18, :minute).to_nanos)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
context "when a value is given as a nanosecond" do
|
|
25
|
+
it "should set the value" do
|
|
26
|
+
subject.set(5)
|
|
27
|
+
expect(subject.value).to eq(LogStash::Util::TimeValue.new(5, :nanosecond).to_nanos)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require "spec_helper"
|
|
3
|
+
require "logstash/settings"
|
|
4
|
+
require "tmpdir"
|
|
5
|
+
require "socket" # for UNIXSocket
|
|
6
|
+
|
|
7
|
+
describe LogStash::Setting::WritableDirectory do
|
|
8
|
+
let(:mode_rx) { 0555 }
|
|
9
|
+
# linux is 108, Macos is 104, so use a safe value
|
|
10
|
+
# Stud::Temporary.pathname, will exceed that size without adding anything
|
|
11
|
+
let(:parent) { File.join(Dir.tmpdir, Time.now.to_f.to_s) }
|
|
12
|
+
let(:path) { File.join(parent, "fancy") }
|
|
13
|
+
|
|
14
|
+
before { Dir.mkdir(parent) }
|
|
15
|
+
after { Dir.exist?(path) && Dir.unlink(path) rescue nil }
|
|
16
|
+
after { Dir.unlink(parent) }
|
|
17
|
+
|
|
18
|
+
shared_examples "failure" do
|
|
19
|
+
before { subject.set(path) }
|
|
20
|
+
it "should fail" do
|
|
21
|
+
expect { subject.validate_value }.to raise_error
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
subject do
|
|
26
|
+
# Create a new WritableDirectory setting with no default value strict
|
|
27
|
+
# disabled.
|
|
28
|
+
described_class.new("fancy.path", "", false)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
describe "#value" do
|
|
32
|
+
before { subject.set(path) }
|
|
33
|
+
|
|
34
|
+
context "when the directory is missing" do
|
|
35
|
+
|
|
36
|
+
context "and the parent is writable" do
|
|
37
|
+
after {
|
|
38
|
+
Dir.unlink(path)
|
|
39
|
+
}
|
|
40
|
+
it "creates the directory" do
|
|
41
|
+
subject.value # need to invoke `#value` to make it do the work.
|
|
42
|
+
expect(::File.directory?(path)).to be_truthy
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
context "and the directory cannot be created" do
|
|
47
|
+
before { File.chmod(mode_rx, parent) }
|
|
48
|
+
it "should fail" do
|
|
49
|
+
expect { subject.value }.to raise_error
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
describe "#set and #validate_value" do
|
|
56
|
+
context "when the directory exists" do
|
|
57
|
+
before { Dir.mkdir(path) }
|
|
58
|
+
after { Dir.unlink(path) }
|
|
59
|
+
|
|
60
|
+
context "and is writable" do
|
|
61
|
+
before { subject.set(path) }
|
|
62
|
+
# assume this spec already created a directory that's writable... fair? :)
|
|
63
|
+
it "should return true" do
|
|
64
|
+
expect(subject.validate_value).to be_truthy
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
context "but is not writable" do
|
|
69
|
+
before { File.chmod(0, path) }
|
|
70
|
+
it_behaves_like "failure"
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
context "when the path exists" do
|
|
75
|
+
after { File.unlink(path) }
|
|
76
|
+
|
|
77
|
+
context "but is a file" do
|
|
78
|
+
before { File.new(path, "w").close }
|
|
79
|
+
it_behaves_like "failure"
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
context "but is a socket" do
|
|
83
|
+
let(:socket) { UNIXServer.new(path) }
|
|
84
|
+
before { socket } # realize `socket` value
|
|
85
|
+
after { socket.close }
|
|
86
|
+
it_behaves_like "failure"
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
context "but is a symlink" do
|
|
90
|
+
before { File::symlink("whatever", path) }
|
|
91
|
+
it_behaves_like "failure"
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
context "when the directory is missing" do
|
|
96
|
+
# Create a path with at least one subdirectory we can try to fiddle with permissions
|
|
97
|
+
|
|
98
|
+
context "but can be created" do
|
|
99
|
+
before do
|
|
100
|
+
# If the path doesn't exist, we want to try creating it, so let's be
|
|
101
|
+
# extra careful and make sure the path doesn't exist yet.
|
|
102
|
+
expect(File.directory?(path)).to be_falsey
|
|
103
|
+
subject.set(path)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
after do
|
|
107
|
+
Dir.unlink(path)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
it "should return true" do
|
|
111
|
+
expect(subject.validate_value).to be_truthy
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
context "and cannot be created" do
|
|
116
|
+
before do
|
|
117
|
+
# Remove write permission on the parent
|
|
118
|
+
File.chmod(mode_rx, parent)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
it_behaves_like "failure"
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|