logstash-core 5.6.16-java → 6.0.0.alpha1-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 +4 -7
- data/lib/logstash-core/logstash-core.jar +0 -0
- data/lib/logstash-core/version.rb +4 -8
- data/lib/logstash-core_jars.rb +12 -26
- data/lib/logstash/agent.rb +261 -246
- data/lib/logstash/api/commands/default_metadata.rb +1 -1
- data/lib/logstash/api/commands/hot_threads_reporter.rb +5 -11
- data/lib/logstash/api/commands/node.rb +3 -2
- data/lib/logstash/api/commands/stats.rb +3 -2
- data/lib/logstash/bootstrap_check/bad_java.rb +16 -0
- data/lib/logstash/bootstrap_check/bad_ruby.rb +12 -0
- data/lib/logstash/bootstrap_check/default_config.rb +17 -0
- data/lib/logstash/compiler.rb +38 -0
- data/lib/logstash/compiler/lscl.rb +566 -0
- data/lib/logstash/compiler/lscl/lscl_grammar.rb +3503 -0
- data/lib/logstash/compiler/treetop_monkeypatches.rb +92 -0
- data/lib/logstash/config/config_ast.rb +4 -82
- data/lib/logstash/config/mixin.rb +73 -41
- data/lib/logstash/config/pipeline_config.rb +48 -0
- data/lib/logstash/config/source/base.rb +16 -0
- data/lib/logstash/config/source/local.rb +215 -0
- data/lib/logstash/config/source_loader.rb +125 -0
- data/lib/logstash/converge_result.rb +103 -0
- data/lib/logstash/environment.rb +6 -19
- data/lib/logstash/errors.rb +2 -0
- data/lib/logstash/execution_context.rb +4 -7
- data/lib/logstash/filter_delegator.rb +6 -9
- data/lib/logstash/inputs/base.rb +0 -2
- data/lib/logstash/instrument/collector.rb +5 -7
- data/lib/logstash/instrument/metric_store.rb +12 -12
- data/lib/logstash/instrument/metric_type/mean.rb +0 -5
- data/lib/logstash/instrument/namespaced_metric.rb +0 -4
- data/lib/logstash/instrument/namespaced_null_metric.rb +0 -4
- data/lib/logstash/instrument/null_metric.rb +0 -10
- data/lib/logstash/instrument/periodic_poller/cgroup.rb +85 -168
- data/lib/logstash/instrument/periodic_poller/jvm.rb +5 -5
- data/lib/logstash/instrument/periodic_poller/pq.rb +3 -7
- data/lib/logstash/instrument/periodic_pollers.rb +1 -3
- data/lib/logstash/instrument/wrapped_write_client.rb +24 -33
- data/lib/logstash/logging/logger.rb +15 -47
- data/lib/logstash/namespace.rb +0 -1
- data/lib/logstash/output_delegator.rb +5 -7
- data/lib/logstash/outputs/base.rb +0 -2
- data/lib/logstash/pipeline.rb +159 -87
- data/lib/logstash/pipeline_action.rb +13 -0
- data/lib/logstash/pipeline_action/base.rb +29 -0
- data/lib/logstash/pipeline_action/create.rb +47 -0
- data/lib/logstash/pipeline_action/reload.rb +48 -0
- data/lib/logstash/pipeline_action/stop.rb +23 -0
- data/lib/logstash/plugin.rb +0 -1
- data/lib/logstash/plugins/hooks_registry.rb +6 -0
- data/lib/logstash/plugins/registry.rb +0 -1
- data/lib/logstash/program.rb +14 -0
- data/lib/logstash/queue_factory.rb +5 -1
- data/lib/logstash/runner.rb +58 -80
- data/lib/logstash/settings.rb +3 -27
- data/lib/logstash/state_resolver.rb +41 -0
- data/lib/logstash/util/java_version.rb +6 -0
- data/lib/logstash/util/safe_uri.rb +12 -148
- data/lib/logstash/util/thread_dump.rb +4 -7
- data/lib/logstash/util/wrapped_acked_queue.rb +36 -39
- data/lib/logstash/util/wrapped_synchronous_queue.rb +29 -39
- data/lib/logstash/version.rb +10 -8
- data/locales/en.yml +3 -54
- data/logstash-core.gemspec +8 -35
- data/spec/{logstash/api/modules → api/lib/api}/logging_spec.rb +10 -1
- data/spec/{logstash/api/modules → api/lib/api}/node_plugins_spec.rb +2 -1
- data/spec/{logstash/api/modules → api/lib/api}/node_spec.rb +3 -3
- data/spec/{logstash/api/modules → api/lib/api}/node_stats_spec.rb +3 -7
- data/spec/{logstash/api/modules → api/lib/api}/plugins_spec.rb +3 -4
- data/spec/{logstash/api/modules → api/lib/api}/root_spec.rb +2 -2
- data/spec/api/lib/api/support/resource_dsl_methods.rb +87 -0
- data/spec/{logstash/api/commands/stats_spec.rb → api/lib/commands/stats.rb} +2 -7
- data/spec/{logstash/api → api/lib}/errors_spec.rb +1 -1
- data/spec/{logstash/api → api/lib}/rack_app_spec.rb +0 -0
- data/spec/api/spec_helper.rb +106 -0
- data/spec/logstash/agent/converge_spec.rb +286 -0
- data/spec/logstash/agent/metrics_spec.rb +244 -0
- data/spec/logstash/agent_spec.rb +213 -225
- data/spec/logstash/compiler/compiler_spec.rb +584 -0
- data/spec/logstash/config/config_ast_spec.rb +8 -47
- data/spec/logstash/config/mixin_spec.rb +2 -42
- data/spec/logstash/config/pipeline_config_spec.rb +75 -0
- data/spec/logstash/config/source/local_spec.rb +395 -0
- data/spec/logstash/config/source_loader_spec.rb +122 -0
- data/spec/logstash/converge_result_spec.rb +179 -0
- data/spec/logstash/event_spec.rb +0 -66
- data/spec/logstash/execution_context_spec.rb +8 -12
- data/spec/logstash/filter_delegator_spec.rb +12 -24
- data/spec/logstash/inputs/base_spec.rb +7 -5
- data/spec/logstash/instrument/periodic_poller/cgroup_spec.rb +92 -225
- data/spec/logstash/instrument/periodic_poller/jvm_spec.rb +1 -1
- data/spec/logstash/instrument/periodic_poller/os_spec.rb +32 -29
- data/spec/logstash/instrument/wrapped_write_client_spec.rb +33 -33
- data/spec/logstash/legacy_ruby_event_spec.rb +13 -4
- data/spec/logstash/output_delegator_spec.rb +11 -20
- data/spec/logstash/outputs/base_spec.rb +7 -5
- data/spec/logstash/pipeline_action/create_spec.rb +83 -0
- data/spec/logstash/pipeline_action/reload_spec.rb +83 -0
- data/spec/logstash/pipeline_action/stop_spec.rb +37 -0
- data/spec/logstash/pipeline_pq_file_spec.rb +1 -1
- data/spec/logstash/pipeline_spec.rb +81 -137
- data/spec/logstash/plugin_spec.rb +2 -1
- data/spec/logstash/plugins/hooks_registry_spec.rb +6 -0
- data/spec/logstash/queue_factory_spec.rb +13 -1
- data/spec/logstash/runner_spec.rb +29 -140
- data/spec/logstash/settings/writable_directory_spec.rb +10 -13
- data/spec/logstash/settings_spec.rb +0 -91
- data/spec/logstash/state_resolver_spec.rb +156 -0
- data/spec/logstash/timestamp_spec.rb +2 -6
- data/spec/logstash/util/java_version_spec.rb +22 -0
- data/spec/logstash/util/safe_uri_spec.rb +0 -56
- data/spec/logstash/util/wrapped_synchronous_queue_spec.rb +22 -0
- data/spec/support/helpers.rb +9 -11
- data/spec/support/matchers.rb +96 -6
- data/spec/support/mocks_classes.rb +80 -0
- data/spec/support/shared_contexts.rb +2 -27
- metadata +100 -149
- data/lib/logstash/config/loader.rb +0 -107
- data/lib/logstash/config/modules_common.rb +0 -103
- data/lib/logstash/config/source/modules.rb +0 -55
- data/lib/logstash/config/string_escape.rb +0 -27
- data/lib/logstash/dependency_report.rb +0 -131
- data/lib/logstash/dependency_report_runner.rb +0 -17
- data/lib/logstash/elasticsearch_client.rb +0 -142
- data/lib/logstash/instrument/global_metrics.rb +0 -13
- data/lib/logstash/instrument/periodic_poller/dlq.rb +0 -24
- data/lib/logstash/modules/cli_parser.rb +0 -74
- data/lib/logstash/modules/elasticsearch_config.rb +0 -22
- data/lib/logstash/modules/elasticsearch_importer.rb +0 -37
- data/lib/logstash/modules/elasticsearch_resource.rb +0 -10
- data/lib/logstash/modules/file_reader.rb +0 -36
- data/lib/logstash/modules/kibana_base.rb +0 -24
- data/lib/logstash/modules/kibana_client.rb +0 -124
- data/lib/logstash/modules/kibana_config.rb +0 -105
- data/lib/logstash/modules/kibana_dashboards.rb +0 -36
- data/lib/logstash/modules/kibana_importer.rb +0 -17
- data/lib/logstash/modules/kibana_resource.rb +0 -10
- data/lib/logstash/modules/kibana_settings.rb +0 -40
- data/lib/logstash/modules/logstash_config.rb +0 -120
- data/lib/logstash/modules/resource_base.rb +0 -38
- data/lib/logstash/modules/scaffold.rb +0 -52
- data/lib/logstash/modules/settings_merger.rb +0 -23
- data/lib/logstash/modules/util.rb +0 -17
- data/lib/logstash/util/dead_letter_queue_manager.rb +0 -61
- data/lib/logstash/util/environment_variables.rb +0 -43
- data/spec/logstash/config/loader_spec.rb +0 -38
- data/spec/logstash/config/string_escape_spec.rb +0 -24
- data/spec/logstash/instrument/periodic_poller/dlq_spec.rb +0 -17
- data/spec/logstash/modules/logstash_config_spec.rb +0 -56
- data/spec/logstash/modules/scaffold_spec.rb +0 -234
- data/spec/logstash/pipeline_dlq_commit_spec.rb +0 -109
- data/spec/logstash/settings/splittable_string_array_spec.rb +0 -51
- data/spec/logstash/util/wrapped_acked_queue_spec.rb +0 -49
- data/versions-gem-copy.yml +0 -12
@@ -0,0 +1,87 @@
|
|
1
|
+
# Ruby doesn't have common class for boolean,
|
2
|
+
# And to simplify the ResourceDSLMethods check it make sense to have it.
|
3
|
+
module Boolean; end
|
4
|
+
class TrueClass
|
5
|
+
include Boolean
|
6
|
+
end
|
7
|
+
class FalseClass
|
8
|
+
include Boolean
|
9
|
+
end
|
10
|
+
|
11
|
+
module ResourceDSLMethods
|
12
|
+
# Convert a nested hash to a mapping of key paths to expected classes
|
13
|
+
def hash_to_mapping(h, path=[], mapping={})
|
14
|
+
h.each do |k,v|
|
15
|
+
if v.is_a?(Hash)
|
16
|
+
hash_to_mapping(v, path + [k], mapping)
|
17
|
+
else
|
18
|
+
full_path = path + [k]
|
19
|
+
mapping[full_path] = v
|
20
|
+
end
|
21
|
+
end
|
22
|
+
mapping
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_api(expected, path)
|
26
|
+
context "GET #{path}" do
|
27
|
+
let(:payload) { LogStash::Json.load(last_response.body) }
|
28
|
+
|
29
|
+
before(:all) do
|
30
|
+
get path
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should respond OK" do
|
34
|
+
expect(last_response).to be_ok
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
describe "the default metadata" do
|
39
|
+
it "should include the host" do
|
40
|
+
expect(payload["host"]).to eql(Socket.gethostname)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should include the version" do
|
44
|
+
expect(payload["version"]).to eql(LOGSTASH_CORE_VERSION)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should include the http address" do
|
48
|
+
expect(payload["http_address"]).to eql("#{Socket.gethostname}:#{::LogStash::WebServer::DEFAULT_PORTS.first}")
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should include the node name" do
|
52
|
+
expect(payload["name"]).to eql(@runner.agent.name)
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should include the node id" do
|
56
|
+
expect(payload["id"]).to eql(@runner.agent.id)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
hash_to_mapping(expected).each do |resource_path,klass|
|
61
|
+
dotted = resource_path.join(".")
|
62
|
+
|
63
|
+
it "should set '#{dotted}' at '#{path}' to be a '#{klass}'" do
|
64
|
+
expect(last_response).to be_ok # fail early if need be
|
65
|
+
resource_path_value = resource_path.reduce(payload) do |acc,v|
|
66
|
+
expect(acc.has_key?(v)).to eql(true), "Expected to find value '#{v}' in structure '#{acc}', but could not. Payload was '#{payload}'"
|
67
|
+
acc[v]
|
68
|
+
end
|
69
|
+
expect(resource_path_value).to be_a(klass), "could not find '#{dotted}' in #{payload}"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
yield if block_given? # Add custom expectations
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_api_and_resources(expected, xopts={})
|
78
|
+
xopts[:exclude_from_root] ||= []
|
79
|
+
root_expectation = expected.clone
|
80
|
+
xopts[:exclude_from_root].each {|k| root_expectation.delete(k)}
|
81
|
+
test_api(root_expectation, "/")
|
82
|
+
|
83
|
+
expected.keys.each do |key|
|
84
|
+
test_api({key => expected[key]}, "/#{key}")
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -1,15 +1,10 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
|
2
|
+
require_relative "../../spec_helper"
|
3
3
|
|
4
4
|
describe LogStash::Api::Commands::Stats do
|
5
|
-
include_context "api setup"
|
6
5
|
|
7
6
|
let(:report_method) { :run }
|
8
|
-
subject(:report)
|
9
|
-
factory = ::LogStash::Api::CommandFactory.new(LogStash::Api::Service.new(@agent))
|
10
|
-
|
11
|
-
factory.build(:stats).send(report_method)
|
12
|
-
end
|
7
|
+
subject(:report) { report_class.new.send(report_method) }
|
13
8
|
|
14
9
|
let(:report_class) { described_class }
|
15
10
|
|
File without changes
|
@@ -0,0 +1,106 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
API_ROOT = File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "lib", "logstash", "api"))
|
3
|
+
|
4
|
+
require "stud/task"
|
5
|
+
require "logstash/devutils/rspec/spec_helper"
|
6
|
+
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__)))
|
7
|
+
require "lib/api/support/resource_dsl_methods"
|
8
|
+
require_relative "../support/mocks_classes"
|
9
|
+
require_relative "../support/helpers"
|
10
|
+
require 'rspec/expectations'
|
11
|
+
require "logstash/settings"
|
12
|
+
require 'rack/test'
|
13
|
+
require 'rspec'
|
14
|
+
require "json"
|
15
|
+
|
16
|
+
def read_fixture(name)
|
17
|
+
path = File.join(File.dirname(__FILE__), "fixtures", name)
|
18
|
+
File.read(path)
|
19
|
+
end
|
20
|
+
|
21
|
+
module LogStash
|
22
|
+
class DummyAgent < Agent
|
23
|
+
def start_webserver
|
24
|
+
http_address = "#{Socket.gethostname}:#{::LogStash::WebServer::DEFAULT_PORTS.first}"
|
25
|
+
@webserver = Struct.new(:address).new(http_address)
|
26
|
+
self.metric.gauge([], :http_address, http_address)
|
27
|
+
end
|
28
|
+
|
29
|
+
def stop_webserver; end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
##
|
34
|
+
# Class used to wrap and manage the execution of an agent for test,
|
35
|
+
# this helps a lot in order to have a more integrated test for the
|
36
|
+
# web api, could be also used for other use cases if generalized enough
|
37
|
+
##
|
38
|
+
class LogStashRunner
|
39
|
+
|
40
|
+
attr_reader :config_str, :agent, :pipeline_settings
|
41
|
+
|
42
|
+
def initialize
|
43
|
+
|
44
|
+
require "securerandom"
|
45
|
+
id = SecureRandom.uuid
|
46
|
+
|
47
|
+
@config_str = "input { generator {id => 'api-generator-pipeline-#{id}' count => 100 } } output { dummyoutput {} }"
|
48
|
+
|
49
|
+
args = {
|
50
|
+
"config.reload.automatic" => false,
|
51
|
+
"metric.collect" => true,
|
52
|
+
"log.level" => "debug",
|
53
|
+
"node.name" => "test_agent",
|
54
|
+
"http.port" => rand(9600..9700),
|
55
|
+
"http.environment" => "test",
|
56
|
+
"config.string" => @config_str,
|
57
|
+
"pipeline.batch.size" => 1,
|
58
|
+
"pipeline.workers" => 1
|
59
|
+
}
|
60
|
+
|
61
|
+
@settings = ::LogStash::SETTINGS.clone.merge(args)
|
62
|
+
source_loader = LogStash::Config::SourceLoader.new
|
63
|
+
source_loader.configure_sources(LogStash::Config::Source::Local.new(@settings))
|
64
|
+
@agent = LogStash::DummyAgent.new(@settings, source_loader)
|
65
|
+
end
|
66
|
+
|
67
|
+
def start
|
68
|
+
# We start a pipeline that will generate a finite number of events
|
69
|
+
# before starting the expectations
|
70
|
+
@agent_task = Stud::Task.new { agent.execute }
|
71
|
+
@agent_task.wait
|
72
|
+
end
|
73
|
+
|
74
|
+
def stop
|
75
|
+
agent.shutdown
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
RSpec::Matchers.define :be_available? do
|
80
|
+
match do |plugin|
|
81
|
+
begin
|
82
|
+
Gem::Specification.find_by_name(plugin["name"])
|
83
|
+
true
|
84
|
+
rescue
|
85
|
+
false
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
shared_context "api setup" do
|
91
|
+
before :all do
|
92
|
+
clear_data_dir
|
93
|
+
@runner = LogStashRunner.new
|
94
|
+
@runner.start
|
95
|
+
end
|
96
|
+
|
97
|
+
after :all do
|
98
|
+
@runner.stop
|
99
|
+
end
|
100
|
+
|
101
|
+
include Rack::Test::Methods
|
102
|
+
|
103
|
+
def app()
|
104
|
+
described_class.new(nil, @runner.agent)
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,286 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/agent"
|
3
|
+
require_relative "../../support/helpers"
|
4
|
+
require_relative "../../support/matchers"
|
5
|
+
require_relative "../../support/mocks_classes"
|
6
|
+
require "spec_helper"
|
7
|
+
|
8
|
+
describe LogStash::Agent do
|
9
|
+
# by default no tests uses the auto reload logic
|
10
|
+
let(:agent_settings) { mock_settings("config.reload.automatic" => false, "queue.type" => "persisted") }
|
11
|
+
|
12
|
+
subject { described_class.new(agent_settings, source_loader) }
|
13
|
+
|
14
|
+
before do
|
15
|
+
clear_data_dir
|
16
|
+
|
17
|
+
# until we decouple the webserver from the agent
|
18
|
+
allow(subject).to receive(:start_webserver).and_return(false)
|
19
|
+
allow(subject).to receive(:stop_webserver).and_return(false)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Make sure that we close any running pipeline to release any pending locks
|
23
|
+
# on the queues
|
24
|
+
after do
|
25
|
+
converge_result = subject.shutdown
|
26
|
+
expect(converge_result).to be_a_successful_converge
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
describe "passing the agent to the pipeline" do
|
31
|
+
let(:source_loader) { TestSourceLoader.new(pipeline_config) }
|
32
|
+
let(:pipeline_config) { mock_pipeline_config(:main, "input { generator { count => 10 } } output { null {} }") }
|
33
|
+
|
34
|
+
before { subject.execute }
|
35
|
+
|
36
|
+
it "execute the pipeline and stop execution" do
|
37
|
+
expect(subject.get_pipeline(:main).execution_context.agent).to eq(subject)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context "Agent execute options" do
|
42
|
+
let(:source_loader) do
|
43
|
+
TestSourceLoader.new(finite_pipeline_config)
|
44
|
+
end
|
45
|
+
|
46
|
+
context "when the pipeline execution is finite" do
|
47
|
+
let(:finite_pipeline_config) { mock_pipeline_config(:main, "input { generator { count => 1000 } } output { null {} }") }
|
48
|
+
|
49
|
+
it "execute the pipeline and stop execution" do
|
50
|
+
expect(subject.execute).to eq(0)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context "when the config is short lived (generator { count => 1 })" do
|
55
|
+
let(:finite_pipeline_config) { mock_pipeline_config(:main, "input { generator { count => 1 } } output { null {} }") }
|
56
|
+
|
57
|
+
it "execute the pipeline and stop execution" do
|
58
|
+
expect(subject.execute).to eq(0)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "system pipeline" do
|
63
|
+
let(:finite_pipeline_config) { mock_pipeline_config(:main, "input { generator { count => 1000 } } output { null {} }") }
|
64
|
+
let(:system_pipeline_config) { mock_pipeline_config(:system_pipeline, "input { generator { } } output { null {} }", { "pipeline.system" => true }) }
|
65
|
+
|
66
|
+
let(:source_loader) do
|
67
|
+
TestSourceLoader.new(finite_pipeline_config, system_pipeline_config)
|
68
|
+
end
|
69
|
+
|
70
|
+
context "when we have a finite pipeline and a system pipeline running" do
|
71
|
+
it "execute the pipeline and stop execution" do
|
72
|
+
expect(subject.execute).to eq(0)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "#running_user_defined_pipelines" do
|
77
|
+
it "returns the user defined pipelines" do
|
78
|
+
agent_task = start_agent(subject)
|
79
|
+
expect(subject.running_user_defined_pipelines.keys).to include(:main)
|
80
|
+
expect(subject.running_user_defined_pipelines.keys).not_to include(:system_pipeline)
|
81
|
+
subject.shutdown
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe "#running_user_defined_pipelines?" do
|
86
|
+
it "returns true" do
|
87
|
+
agent_task = start_agent(subject)
|
88
|
+
expect(subject.running_user_defined_pipelines?).to be_truthy
|
89
|
+
subject.shutdown
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context "when `config.reload.automatic`" do
|
95
|
+
let(:pipeline_config) { mock_pipeline_config(:main, "input { generator {} } output { null {} }") }
|
96
|
+
|
97
|
+
let(:source_loader) do
|
98
|
+
TestSourceLoader.new(pipeline_config)
|
99
|
+
end
|
100
|
+
|
101
|
+
context "is set to`FALSE`" do
|
102
|
+
context "and successfully load the config" do
|
103
|
+
let(:agent_settings) { mock_settings("config.reload.automatic" => false) }
|
104
|
+
|
105
|
+
it "converge only once" do
|
106
|
+
agent_task = start_agent(subject)
|
107
|
+
|
108
|
+
expect(source_loader.fetch_count).to eq(1)
|
109
|
+
expect(subject).to have_running_pipeline?(pipeline_config)
|
110
|
+
|
111
|
+
subject.shutdown
|
112
|
+
agent_task.stop!
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
context "and it fails to load the config" do
|
117
|
+
let(:source_loader) do
|
118
|
+
TestSourceLoader.new(TestSourceLoader::FailedFetch.new("can't load the file"))
|
119
|
+
end
|
120
|
+
|
121
|
+
it "doesn't execute any pipeline" do
|
122
|
+
expect { subject.execute }.not_to raise_error # errors is logged
|
123
|
+
|
124
|
+
expect(source_loader.fetch_count).to eq(1)
|
125
|
+
expect(subject.pipelines_count).to eq(0)
|
126
|
+
|
127
|
+
subject.shutdown
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
context "is set to `TRUE`" do
|
133
|
+
let(:interval) { 0.01 }
|
134
|
+
let(:agent_settings) do
|
135
|
+
mock_settings(
|
136
|
+
"config.reload.automatic" => true,
|
137
|
+
"config.reload.interval" => interval
|
138
|
+
)
|
139
|
+
end
|
140
|
+
|
141
|
+
context "and successfully load the config" do
|
142
|
+
it "converges periodically the pipelines from the configs source" do
|
143
|
+
agent_task = start_agent(subject)
|
144
|
+
|
145
|
+
sleep(2) # let the interval reload a few times
|
146
|
+
expect(subject).to have_running_pipeline?(pipeline_config)
|
147
|
+
|
148
|
+
# we rely on a periodic thread to call fetch count, we have seen unreliable run on
|
149
|
+
# travis, so lets add a few retries
|
150
|
+
try do
|
151
|
+
expect(source_loader.fetch_count).to be > 1
|
152
|
+
end
|
153
|
+
|
154
|
+
subject.shutdown
|
155
|
+
agent_task.stop!
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
context "and it fails to load the config" do
|
160
|
+
let(:source_loader) do
|
161
|
+
TestSourceLoader.new(TestSourceLoader::FailedFetch.new("can't load the file"))
|
162
|
+
end
|
163
|
+
|
164
|
+
it "it will keep trying to converge" do
|
165
|
+
agent_task = start_agent(subject)
|
166
|
+
|
167
|
+
sleep(interval * 20) # let the interval reload a few times
|
168
|
+
expect(subject.pipelines_count).to eq(0)
|
169
|
+
expect(source_loader.fetch_count).to be > 1
|
170
|
+
|
171
|
+
subject.shutdown
|
172
|
+
agent_task.stop!
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
context "when shutting down the agent" do
|
180
|
+
let(:pipeline_config) { mock_pipeline_config(:main, "input { generator {} } output { null {} }") }
|
181
|
+
let(:new_pipeline_config) { mock_pipeline_config(:new, "input { generator { id => 'new' } } output { null {} }") }
|
182
|
+
|
183
|
+
let(:source_loader) do
|
184
|
+
TestSourceLoader.new([pipeline_config, new_pipeline_config])
|
185
|
+
end
|
186
|
+
|
187
|
+
it "stops the running pipelines" do
|
188
|
+
expect(subject.converge_state_and_update).to be_a_successful_converge
|
189
|
+
expect { subject.shutdown }.to change { subject.running_pipelines.size }.from(2).to(0)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
context "Configuration converge scenario" do
|
194
|
+
let(:pipeline_config) { mock_pipeline_config(:main, "input { generator {} } output { null {} }", { "pipeline.reloadable" => true }) }
|
195
|
+
let(:new_pipeline_config) { mock_pipeline_config(:new, "input { generator {} } output { null {} }", { "pipeline.reloadable" => true }) }
|
196
|
+
|
197
|
+
before do
|
198
|
+
# Set the Agent to an initial state of pipelines
|
199
|
+
expect(subject.converge_state_and_update).to be_a_successful_converge
|
200
|
+
end
|
201
|
+
|
202
|
+
context "no pipelines is running" do
|
203
|
+
let(:source_loader) do
|
204
|
+
TestSequenceSourceLoader.new([], pipeline_config)
|
205
|
+
end
|
206
|
+
|
207
|
+
it "creates and starts the new pipeline" do
|
208
|
+
expect {
|
209
|
+
expect(subject.converge_state_and_update).to be_a_successful_converge
|
210
|
+
}.to change { subject.running_pipelines.count }.from(0).to(1)
|
211
|
+
expect(subject).to have_running_pipeline?(pipeline_config)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
context "when a pipeline is running" do
|
216
|
+
context "when the source returns the current pipeline and a new one" do
|
217
|
+
let(:source_loader) do
|
218
|
+
TestSequenceSourceLoader.new(
|
219
|
+
pipeline_config,
|
220
|
+
[pipeline_config, new_pipeline_config]
|
221
|
+
)
|
222
|
+
end
|
223
|
+
|
224
|
+
it "start a new pipeline and keep the original" do
|
225
|
+
expect {
|
226
|
+
expect(subject.converge_state_and_update).to be_a_successful_converge
|
227
|
+
}.to change { subject.running_pipelines.count }.from(1).to(2)
|
228
|
+
expect(subject).to have_running_pipeline?(pipeline_config)
|
229
|
+
expect(subject).to have_running_pipeline?(new_pipeline_config)
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
context "when the source returns a new pipeline but not the old one" do
|
234
|
+
let(:source_loader) do
|
235
|
+
TestSequenceSourceLoader.new(
|
236
|
+
pipeline_config,
|
237
|
+
new_pipeline_config
|
238
|
+
)
|
239
|
+
end
|
240
|
+
|
241
|
+
it "stops the missing pipeline and start the new one" do
|
242
|
+
expect {
|
243
|
+
expect(subject.converge_state_and_update).to be_a_successful_converge
|
244
|
+
}.not_to change { subject.running_pipelines.count }
|
245
|
+
expect(subject).not_to have_pipeline?(pipeline_config)
|
246
|
+
expect(subject).to have_running_pipeline?(new_pipeline_config)
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
context "when the source return a modified pipeline" do
|
252
|
+
let(:modified_pipeline_config) { mock_pipeline_config(:main, "input { generator { id => 'new-and-modified' } } output { null {} }", { "pipeline.reloadable" => true }) }
|
253
|
+
|
254
|
+
let(:source_loader) do
|
255
|
+
TestSequenceSourceLoader.new(
|
256
|
+
[pipeline_config],
|
257
|
+
[modified_pipeline_config]
|
258
|
+
)
|
259
|
+
end
|
260
|
+
|
261
|
+
it "reloads the modified pipeline" do
|
262
|
+
expect {
|
263
|
+
expect(subject.converge_state_and_update).to be_a_successful_converge
|
264
|
+
}.not_to change { subject.running_pipelines.count }
|
265
|
+
expect(subject).to have_running_pipeline?(modified_pipeline_config)
|
266
|
+
expect(subject).not_to have_pipeline?(pipeline_config)
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
context "when the source return no pipelines" do
|
271
|
+
let(:source_loader) do
|
272
|
+
TestSequenceSourceLoader.new(
|
273
|
+
[pipeline_config, new_pipeline_config],
|
274
|
+
[]
|
275
|
+
)
|
276
|
+
end
|
277
|
+
|
278
|
+
it "stops all the pipelines" do
|
279
|
+
expect {
|
280
|
+
expect(subject.converge_state_and_update).to be_a_successful_converge
|
281
|
+
}.to change { subject.running_pipelines.count }.from(2).to(0)
|
282
|
+
expect(subject).not_to have_pipeline?(pipeline_config)
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|