logstash-core 2.0.1.snapshot1-java → 2.1.0-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/lib/logstash/agent.rb +21 -6
- data/lib/logstash/config/mixin.rb +0 -6
- data/lib/logstash/event.rb +1 -1
- data/lib/logstash/filters/base.rb +1 -2
- data/lib/logstash/inputs/base.rb +0 -5
- data/lib/logstash/outputs/base.rb +7 -5
- data/lib/logstash/pipeline.rb +85 -15
- data/lib/logstash/plugin.rb +5 -0
- data/lib/logstash/shutdown_controller.rb +127 -0
- data/lib/logstash/util.rb +35 -0
- data/lib/logstash/util/defaults_printer.rb +1 -1
- data/lib/logstash/util/worker_threads_default_printer.rb +14 -2
- data/lib/logstash/version.rb +1 -1
- data/locales/en.yml +5 -0
- data/logstash-core.gemspec +2 -1
- data/spec/core/event_spec.rb +19 -0
- data/spec/core/pipeline_spec.rb +113 -7
- data/spec/core/shutdown_controller_spec.rb +107 -0
- data/spec/license_spec.rb +1 -0
- data/spec/plugin_manager/install_spec.rb +28 -0
- data/spec/plugin_manager/update_spec.rb +39 -0
- data/spec/plugin_manager/util_spec.rb +71 -0
- data/spec/util/compress_spec.rb +121 -0
- data/spec/util/defaults_printer_spec.rb +3 -2
- data/spec/util/worker_threads_default_printer_spec.rb +30 -11
- metadata +76 -54
- data/lib/logstash/util/reporter.rb +0 -28
- data/spec/pluginmanager/util_spec.rb +0 -42
data/lib/logstash/util.rb
CHANGED
|
@@ -24,6 +24,41 @@ module LogStash::Util
|
|
|
24
24
|
end
|
|
25
25
|
end # def set_thread_name
|
|
26
26
|
|
|
27
|
+
def self.set_thread_plugin(plugin)
|
|
28
|
+
Thread.current[:plugin] = plugin
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def self.get_thread_id(thread)
|
|
32
|
+
if RUBY_ENGINE == "jruby"
|
|
33
|
+
JRuby.reference(thread).native_thread.id
|
|
34
|
+
else
|
|
35
|
+
raise Exception.new("Native thread IDs aren't supported outside of JRuby")
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def self.thread_info(thread)
|
|
40
|
+
backtrace = thread.backtrace.map do |line|
|
|
41
|
+
line.gsub(LogStash::Environment::LOGSTASH_HOME, "[...]")
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
blocked_on = case backtrace.first
|
|
45
|
+
when /in `push'/ then "blocked_on_push"
|
|
46
|
+
when /(?:pipeline|base).*pop/ then "waiting_for_events"
|
|
47
|
+
else nil
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
{
|
|
51
|
+
"thread_id" => get_thread_id(thread),
|
|
52
|
+
"name" => thread[:name],
|
|
53
|
+
"plugin" => (thread[:plugin] ? thread[:plugin].debug_info : nil),
|
|
54
|
+
"backtrace" => backtrace,
|
|
55
|
+
"blocked_on" => blocked_on,
|
|
56
|
+
"status" => thread.status,
|
|
57
|
+
"current_call" => backtrace.first
|
|
58
|
+
}
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
|
|
27
62
|
# Merge hash 'src' into 'dst' nondestructively
|
|
28
63
|
#
|
|
29
64
|
# Duplicate keys will become array values
|
|
@@ -6,11 +6,23 @@ require "logstash/util"
|
|
|
6
6
|
module LogStash module Util class WorkerThreadsDefaultPrinter
|
|
7
7
|
|
|
8
8
|
def initialize(settings)
|
|
9
|
-
@setting = settings.fetch('filter-workers',
|
|
9
|
+
@setting = settings.fetch('filter-workers', 0)
|
|
10
|
+
@default = settings.fetch('default-filter-workers', 0)
|
|
10
11
|
end
|
|
11
12
|
|
|
12
13
|
def visit(collector)
|
|
13
|
-
collector
|
|
14
|
+
visit_setting(collector)
|
|
15
|
+
visit_default(collector)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def visit_setting(collector)
|
|
19
|
+
return if @setting == 0
|
|
20
|
+
collector.push("User set filter workers: #{@setting}")
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def visit_default(collector)
|
|
24
|
+
return if @default == 0
|
|
25
|
+
collector.push "Default filter workers: #{@default}"
|
|
14
26
|
end
|
|
15
27
|
|
|
16
28
|
end end end
|
data/lib/logstash/version.rb
CHANGED
data/locales/en.yml
CHANGED
|
@@ -187,3 +187,8 @@ en:
|
|
|
187
187
|
debug: |+
|
|
188
188
|
Most verbose logging. This causes 'debug'
|
|
189
189
|
level logs to be emitted.
|
|
190
|
+
unsafe_shutdown: |+
|
|
191
|
+
Force logstash to exit during shutdown even
|
|
192
|
+
if there are still inflight events in memory.
|
|
193
|
+
By default, logstash will refuse to quit until all
|
|
194
|
+
received events have been pushed to the outputs.
|
data/logstash-core.gemspec
CHANGED
|
@@ -23,7 +23,7 @@ Gem::Specification.new do |gem|
|
|
|
23
23
|
gem.add_runtime_dependency "clamp", "~> 0.6.5" #(MIT license) for command line args/flags
|
|
24
24
|
gem.add_runtime_dependency "filesize", "0.0.4" #(MIT license) for :bytes config validator
|
|
25
25
|
gem.add_runtime_dependency "gems", "~> 0.8.3" #(MIT license)
|
|
26
|
-
gem.add_runtime_dependency "concurrent-ruby", "
|
|
26
|
+
gem.add_runtime_dependency "concurrent-ruby", "0.9.2"
|
|
27
27
|
gem.add_runtime_dependency "jruby-openssl", ">= 0.9.11" # Required to support TLSv1.2
|
|
28
28
|
|
|
29
29
|
# TODO(sissel): Treetop 1.5.x doesn't seem to work well, but I haven't
|
|
@@ -35,6 +35,7 @@ Gem::Specification.new do |gem|
|
|
|
35
35
|
|
|
36
36
|
# filetools and rakelib
|
|
37
37
|
gem.add_runtime_dependency "minitar", "~> 0.5.4"
|
|
38
|
+
gem.add_runtime_dependency "rubyzip", "~> 1.1.7"
|
|
38
39
|
gem.add_runtime_dependency "thread_safe", "~> 0.3.5" #(Apache 2.0 license)
|
|
39
40
|
|
|
40
41
|
if RUBY_PLATFORM == 'java'
|
data/spec/core/event_spec.rb
CHANGED
|
@@ -496,4 +496,23 @@ describe LogStash::Event do
|
|
|
496
496
|
subject{LogStash::Event.new(LogStash::Json.load(LogStash::Json.dump(event_hash)))}
|
|
497
497
|
end
|
|
498
498
|
end
|
|
499
|
+
|
|
500
|
+
|
|
501
|
+
describe "#to_s" do
|
|
502
|
+
let(:timestamp) { LogStash::Timestamp.new }
|
|
503
|
+
let(:event1) { LogStash::Event.new({ "@timestamp" => timestamp, "host" => "foo", "message" => "bar"}) }
|
|
504
|
+
let(:event2) { LogStash::Event.new({ "host" => "bar", "message" => "foo"}) }
|
|
505
|
+
|
|
506
|
+
it "should cache only one template" do
|
|
507
|
+
LogStash::StringInterpolation::CACHE.clear
|
|
508
|
+
expect {
|
|
509
|
+
event1.to_s
|
|
510
|
+
event2.to_s
|
|
511
|
+
}.to change { LogStash::StringInterpolation::CACHE.size }.by(1)
|
|
512
|
+
end
|
|
513
|
+
|
|
514
|
+
it "return the string containing the timestamp, the host and the message" do
|
|
515
|
+
expect(event1.to_s).to eq("#{timestamp.to_iso8601} #{event1["host"]} #{event1["message"]}")
|
|
516
|
+
end
|
|
517
|
+
end
|
|
499
518
|
end
|
data/spec/core/pipeline_spec.rb
CHANGED
|
@@ -53,20 +53,127 @@ class DummyOutput < LogStash::Outputs::Base
|
|
|
53
53
|
end
|
|
54
54
|
end
|
|
55
55
|
|
|
56
|
+
class DummyFilter < LogStash::Filters::Base
|
|
57
|
+
config_name "dummyfilter"
|
|
58
|
+
milestone 2
|
|
59
|
+
|
|
60
|
+
def register() end
|
|
61
|
+
|
|
62
|
+
def filter(event) end
|
|
63
|
+
|
|
64
|
+
def threadsafe?() false; end
|
|
65
|
+
|
|
66
|
+
def close() end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
class DummySafeFilter < LogStash::Filters::Base
|
|
70
|
+
config_name "dummysafefilter"
|
|
71
|
+
milestone 2
|
|
72
|
+
|
|
73
|
+
def register() end
|
|
74
|
+
|
|
75
|
+
def filter(event) end
|
|
76
|
+
|
|
77
|
+
def threadsafe?() true; end
|
|
78
|
+
|
|
79
|
+
def close() end
|
|
80
|
+
end
|
|
81
|
+
|
|
56
82
|
class TestPipeline < LogStash::Pipeline
|
|
57
|
-
attr_reader :outputs
|
|
83
|
+
attr_reader :outputs, :filter_threads, :settings, :logger
|
|
58
84
|
end
|
|
59
85
|
|
|
60
86
|
describe LogStash::Pipeline do
|
|
87
|
+
let(:worker_thread_count) { 8 }
|
|
88
|
+
let(:safe_thread_count) { 1 }
|
|
89
|
+
let(:override_thread_count) { 42 }
|
|
90
|
+
|
|
91
|
+
describe "defaulting the filter workers based on thread safety" do
|
|
92
|
+
before(:each) do
|
|
93
|
+
allow(LogStash::Plugin).to receive(:lookup).with("input", "dummyinput").and_return(DummyInput)
|
|
94
|
+
allow(LogStash::Plugin).to receive(:lookup).with("codec", "plain").and_return(DummyCodec)
|
|
95
|
+
allow(LogStash::Plugin).to receive(:lookup).with("output", "dummyoutput").and_return(DummyOutput)
|
|
96
|
+
allow(LogStash::Plugin).to receive(:lookup).with("filter", "dummyfilter").and_return(DummyFilter)
|
|
97
|
+
allow(LogStash::Plugin).to receive(:lookup).with("filter", "dummysafefilter").and_return(DummySafeFilter)
|
|
98
|
+
allow(LogStash::Config::CpuCoreStrategy).to receive(:fifty_percent).and_return(worker_thread_count)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
context "when there are some not threadsafe filters" do
|
|
102
|
+
let(:test_config_with_filters) {
|
|
103
|
+
<<-eos
|
|
104
|
+
input {
|
|
105
|
+
dummyinput {}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
filter {
|
|
109
|
+
dummyfilter {}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
output {
|
|
113
|
+
dummyoutput {}
|
|
114
|
+
}
|
|
115
|
+
eos
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
context "when there is no command line -w N set" do
|
|
119
|
+
it "starts one filter thread" do
|
|
120
|
+
msg = "Defaulting filter worker threads to 1 because there are some" +
|
|
121
|
+
" filters that might not work with multiple worker threads"
|
|
122
|
+
pipeline = TestPipeline.new(test_config_with_filters)
|
|
123
|
+
expect(pipeline.logger).to receive(:warn).with(msg,
|
|
124
|
+
{:count_was=>worker_thread_count, :filters=>["dummyfilter"]})
|
|
125
|
+
pipeline.run
|
|
126
|
+
expect(pipeline.filter_threads.size).to eq(safe_thread_count)
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
context "when there is command line -w N set" do
|
|
131
|
+
it "starts multiple filter thread" do
|
|
132
|
+
msg = "Warning: Manual override - there are filters that might" +
|
|
133
|
+
" not work with multiple worker threads"
|
|
134
|
+
pipeline = TestPipeline.new(test_config_with_filters)
|
|
135
|
+
expect(pipeline.logger).to receive(:warn).with(msg,
|
|
136
|
+
{:worker_threads=> override_thread_count, :filters=>["dummyfilter"]})
|
|
137
|
+
pipeline.configure("filter-workers", override_thread_count)
|
|
138
|
+
pipeline.run
|
|
139
|
+
expect(pipeline.filter_threads.size).to eq(override_thread_count)
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
context "when there are threadsafe filters only" do
|
|
145
|
+
let(:test_config_with_filters) {
|
|
146
|
+
<<-eos
|
|
147
|
+
input {
|
|
148
|
+
dummyinput {}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
filter {
|
|
152
|
+
dummysafefilter {}
|
|
153
|
+
}
|
|
61
154
|
|
|
62
|
-
|
|
155
|
+
output {
|
|
156
|
+
dummyoutput {}
|
|
157
|
+
}
|
|
158
|
+
eos
|
|
159
|
+
}
|
|
63
160
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
161
|
+
it "starts multiple filter threads" do
|
|
162
|
+
pipeline = TestPipeline.new(test_config_with_filters)
|
|
163
|
+
pipeline.run
|
|
164
|
+
expect(pipeline.filter_threads.size).to eq(worker_thread_count)
|
|
165
|
+
end
|
|
166
|
+
end
|
|
68
167
|
end
|
|
69
168
|
|
|
169
|
+
context "close" do
|
|
170
|
+
before(:each) do
|
|
171
|
+
allow(LogStash::Plugin).to receive(:lookup).with("input", "dummyinput").and_return(DummyInput)
|
|
172
|
+
allow(LogStash::Plugin).to receive(:lookup).with("codec", "plain").and_return(DummyCodec)
|
|
173
|
+
allow(LogStash::Plugin).to receive(:lookup).with("output", "dummyoutput").and_return(DummyOutput)
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
|
|
70
177
|
let(:test_config_without_output_workers) {
|
|
71
178
|
<<-eos
|
|
72
179
|
input {
|
|
@@ -191,6 +298,5 @@ context "close" do
|
|
|
191
298
|
expect(subject[2]["foo"]).to eq("bar")
|
|
192
299
|
end
|
|
193
300
|
end
|
|
194
|
-
|
|
195
301
|
end
|
|
196
302
|
end
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require "spec_helper"
|
|
3
|
+
require "logstash/shutdown_controller"
|
|
4
|
+
|
|
5
|
+
describe LogStash::ShutdownController do
|
|
6
|
+
|
|
7
|
+
let(:check_every) { 0.01 }
|
|
8
|
+
let(:check_threshold) { 100 }
|
|
9
|
+
subject { LogStash::ShutdownController.new(pipeline, check_every) }
|
|
10
|
+
let(:pipeline) { double("pipeline") }
|
|
11
|
+
report_count = 0
|
|
12
|
+
|
|
13
|
+
before :each do
|
|
14
|
+
allow(LogStash::Report).to receive(:from_pipeline).and_wrap_original do |m, *args|
|
|
15
|
+
report_count += 1
|
|
16
|
+
m.call(*args)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
after :each do
|
|
21
|
+
report_count = 0
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
context "when pipeline is stalled" do
|
|
25
|
+
let(:increasing_count) { (1..5000).to_a.map {|i| { "total" => i } } }
|
|
26
|
+
before :each do
|
|
27
|
+
allow(pipeline).to receive(:inflight_count).and_return(*increasing_count)
|
|
28
|
+
allow(pipeline).to receive(:stalling_threads) { { } }
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
describe ".unsafe_shutdown = true" do
|
|
32
|
+
let(:abort_threshold) { subject.abort_threshold }
|
|
33
|
+
let(:report_every) { subject.report_every }
|
|
34
|
+
|
|
35
|
+
before :each do
|
|
36
|
+
subject.class.unsafe_shutdown = true
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "should force the shutdown" do
|
|
40
|
+
expect(subject).to receive(:force_exit).once
|
|
41
|
+
subject.start
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it "should do exactly \"abort_threshold\" stall checks" do
|
|
45
|
+
allow(subject).to receive(:force_exit)
|
|
46
|
+
expect(subject).to receive(:shutdown_stalled?).exactly(abort_threshold).times.and_call_original
|
|
47
|
+
subject.start
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it "should do exactly \"abort_threshold\"*\"report_every\" stall checks" do
|
|
51
|
+
allow(subject).to receive(:force_exit)
|
|
52
|
+
expect(LogStash::Report).to receive(:from_pipeline).exactly(abort_threshold*report_every).times.and_call_original
|
|
53
|
+
subject.start
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
describe ".unsafe_shutdown = false" do
|
|
58
|
+
|
|
59
|
+
before :each do
|
|
60
|
+
subject.class.unsafe_shutdown = false
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "shouldn't force the shutdown" do
|
|
64
|
+
expect(subject).to_not receive(:force_exit)
|
|
65
|
+
thread = Thread.new(subject) {|subject| subject.start }
|
|
66
|
+
sleep 0.1 until report_count > check_threshold
|
|
67
|
+
thread.kill
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
context "when pipeline is not stalled" do
|
|
73
|
+
let(:decreasing_count) { (1..5000).to_a.reverse.map {|i| { "total" => i } } }
|
|
74
|
+
before :each do
|
|
75
|
+
allow(pipeline).to receive(:inflight_count).and_return(*decreasing_count)
|
|
76
|
+
allow(pipeline).to receive(:stalling_threads) { { } }
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
describe ".unsafe_shutdown = true" do
|
|
80
|
+
|
|
81
|
+
before :each do
|
|
82
|
+
subject.class.unsafe_shutdown = true
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it "should force the shutdown" do
|
|
86
|
+
expect(subject).to_not receive(:force_exit)
|
|
87
|
+
thread = Thread.new(subject) {|subject| subject.start }
|
|
88
|
+
sleep 0.1 until report_count > check_threshold
|
|
89
|
+
thread.kill
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
describe ".unsafe_shutdown = false" do
|
|
94
|
+
|
|
95
|
+
before :each do
|
|
96
|
+
subject.class.unsafe_shutdown = false
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it "shouldn't force the shutdown" do
|
|
100
|
+
expect(subject).to_not receive(:force_exit)
|
|
101
|
+
thread = Thread.new(subject) {|subject| subject.start }
|
|
102
|
+
sleep 0.1 until report_count > check_threshold
|
|
103
|
+
thread.kill
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
data/spec/license_spec.rb
CHANGED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
require 'pluginmanager/main'
|
|
4
|
+
|
|
5
|
+
describe LogStash::PluginManager::Install do
|
|
6
|
+
let(:cmd) { LogStash::PluginManager::Install.new("install") }
|
|
7
|
+
|
|
8
|
+
before(:each) do
|
|
9
|
+
expect(cmd).to receive(:validate_cli_options!).and_return(nil)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
context "when validating plugins" do
|
|
13
|
+
let(:sources) { ["https://rubygems.org", "http://localhost:9292"] }
|
|
14
|
+
|
|
15
|
+
before(:each) do
|
|
16
|
+
expect(cmd).to receive(:plugins_gems).and_return([["dummy", nil]])
|
|
17
|
+
expect(cmd).to receive(:install_gems_list!).and_return(nil)
|
|
18
|
+
expect(cmd).to receive(:remove_unused_locally_installed_gems!).and_return(nil)
|
|
19
|
+
cmd.verify = true
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "should load all the sources defined in the Gemfile" do
|
|
23
|
+
expect(cmd.gemfile.gemset).to receive(:sources).and_return(sources)
|
|
24
|
+
expect(LogStash::PluginManager).to receive(:logstash_plugin?).with("dummy", nil, {:rubygems_source => sources}).and_return(true)
|
|
25
|
+
cmd.execute
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
require 'pluginmanager/main'
|
|
4
|
+
|
|
5
|
+
describe LogStash::PluginManager::Update do
|
|
6
|
+
let(:cmd) { LogStash::PluginManager::Update.new("update") }
|
|
7
|
+
let(:sources) { cmd.gemfile.gemset.sources }
|
|
8
|
+
|
|
9
|
+
before(:each) do
|
|
10
|
+
expect(cmd).to receive(:find_latest_gem_specs).and_return({})
|
|
11
|
+
allow(cmd).to receive(:warn_local_gems).and_return(nil)
|
|
12
|
+
expect(cmd).to receive(:display_updated_plugins).and_return(nil)
|
|
13
|
+
expect_any_instance_of(LogStash::Bundler).to receive(:invoke!).with(:clean => true)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "pass all gem sources to the bundle update command" do
|
|
17
|
+
sources = cmd.gemfile.gemset.sources
|
|
18
|
+
expect_any_instance_of(LogStash::Bundler).to receive(:invoke!).with(:update => [], :rubygems_source => sources)
|
|
19
|
+
cmd.execute
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
context "when skipping validation" do
|
|
23
|
+
let(:cmd) { LogStash::PluginManager::Update.new("update") }
|
|
24
|
+
let(:plugin) { OpenStruct.new(:name => "dummy", :options => {} ) }
|
|
25
|
+
|
|
26
|
+
before(:each) do
|
|
27
|
+
expect(cmd.gemfile).to receive(:find).with(plugin).and_return(plugin)
|
|
28
|
+
expect(cmd.gemfile).to receive(:save).and_return(nil)
|
|
29
|
+
expect(cmd).to receive(:plugins_to_update).and_return([plugin])
|
|
30
|
+
expect_any_instance_of(LogStash::Bundler).to receive(:invoke!).with(:update => [plugin], :rubygems_source => sources).and_return(nil)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "skips version verification when ask for it" do
|
|
34
|
+
cmd.verify = false
|
|
35
|
+
expect(cmd).to_not receive(:validates_version)
|
|
36
|
+
cmd.execute
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|