# encoding: UTF-8
require_relative 'spec_helper'
shared_context 'keep_forward_init' do
before { Fluent::Test.setup }
CONFIG = %[
host localhost
port 24224
host localhost
port 24225
]
let(:tag) { 'syslog.host1' }
let(:chunk) { [1] }
let(:config) { CONFIG }
let(:driver) { Fluent::Test::OutputTestDriver.new(Fluent::KeepForwardOutput, tag).configure(config).instance }
end
shared_context 'keep_forward_try_once' do
before do
# stub connection
stub_sock = StringIO.new
driver.stub(:connect).and_return { stub_sock }
stub_sock.stub(:setsockopt)
driver.stub(:sock_write).and_return { nil }
Fluent::ForwardOutput::Node.any_instance.stub(:heartbeat).and_return { nil }
# simpler version of Fluent::ForwardOutput#start method
driver.watcher_interval = 0
driver.start_watcher
driver.instance_variable_set(:@rand_seed, Random.new.seed)
driver.send(:rebuild_weight_array)
driver.instance_variable_set(:@rr, 0)
driver.write_objects(tag, chunk)
end
after do
driver.stop_watcher
end
let!(:keep_node) { driver.get_node(tag) }
let!(:another_node) { (driver.instance_variable_get(:@nodes) - [keep_node]).first }
end
shared_examples "keep_node_available" do
it { driver.write_objects(tag, chunk) }
end
shared_examples "keep_node_not_available" do
before { keep_node.available = false }
it { driver.write_objects(tag, chunk) }
end
shared_examples "prefer_recover false" do
let(:config) { CONFIG + %[prefer_recover false] }
before { driver.instance_variable_set(:@weight_array, [another_node]) }
it { driver.write_objects(tag, chunk) }
end
shared_context "prefer_recover true" do
let(:config) { CONFIG + %[prefer_recover true] }
before { driver.instance_variable_set(:@weight_array, [another_node]) }
it { driver.write_objects(tag, chunk) }
end
shared_examples "error_occurs" do
before { driver.stub(:send_data).with(keep_node, tag, chunk).and_raise(StandardError) }
it { driver.write_objects(tag, chunk) }
end
describe Fluent::KeepForwardOutput do
include_context 'keep_forward_init'
include_context 'keep_forward_try_once'
describe "keep_node" do
it_should_behave_like 'keep_node_available' do
before { driver.should_receive(:send_data).with(keep_node, tag, chunk) }
end
it_should_behave_like 'keep_node_not_available' do
before { driver.should_receive(:send_data).with(another_node, tag, chunk) }
end
it_should_behave_like 'prefer_recover true' do
before { driver.should_receive(:send_data).with(another_node, tag, chunk) }
end
it_should_behave_like 'prefer_recover false' do
before { driver.should_receive(:send_data).with(keep_node, tag, chunk) }
end
it_should_behave_like 'error_occurs' do
before { driver.stub(:weight_send_data).with(tag, chunk) } # re-call weight_send_data
end
end
describe "keepalive false" do
let(:config) { CONFIG + %[keepalive false] }
it_should_behave_like 'keep_node_available' do
before { driver.should_receive(:reconnect) }
end
it_should_behave_like 'keep_node_not_available' do
before { driver.should_receive(:reconnect) }
end
it_should_behave_like 'prefer_recover true' do
let(:config) { CONFIG + %[prefer_recover true\nkeepalive false] }
before { driver.should_receive(:reconnect) }
end
it_should_behave_like 'prefer_recover false' do
let(:config) { CONFIG + %[prefer_recover false\nkeepalive false] }
before { driver.should_receive(:reconnect) }
end
end
describe "keepalive true" do
let(:config) { CONFIG + %[keepalive true] }
it_should_behave_like 'keep_node_available' do
before { driver.should_not_receive(:reconnect) }
end
it_should_behave_like 'keep_node_not_available' do
before { driver.should_receive(:reconnect) }
end
it_should_behave_like 'prefer_recover true' do
let(:config) { CONFIG + %[prefer_recover true\nkeepalive true] }
before { driver.should_receive(:reconnect) }
end
it_should_behave_like 'prefer_recover false' do
let(:config) { CONFIG + %[prefer_recover false\nkeepalive true] }
before { driver.should_not_receive(:reconnect) }
end
end
describe "keepalive_time expired" do
let(:config) { CONFIG + %[keepalive true\nkeepalive_time 30] }
before { Delorean.jump 30 }
it_should_behave_like 'keep_node_available' do
before { sleep 1; driver.should_receive(:reconnect) }
end
it_should_behave_like 'keep_node_not_available' do
before { sleep 1; driver.should_receive(:reconnect) }
end
it_should_behave_like 'prefer_recover true' do
let(:config) { CONFIG + %[prefer_recover true\nkeepalive true\nkeepalive_time 30] }
before { sleep 1; driver.should_receive(:reconnect) }
end
it_should_behave_like 'prefer_recover false' do
let(:config) { CONFIG + %[prefer_recover false\nkeepalive true\nkeepalive_time 30] }
before { sleep 1; driver.should_receive(:reconnect) }
end
end
end