Merge pull request #16 from treasure-data/redesign_fluentd_management

[wip] fix up fluentd process management
This commit is contained in:
uu59 2014-05-23 17:32:08 +09:00
commit 94e1f7fd39
30 changed files with 715 additions and 168 deletions

View File

@ -5,7 +5,7 @@ PATH
bcrypt (~> 3.1.5)
bundler (~> 1.5)
coffee-rails (~> 4.0.0)
fluentd (= 0.10.46)
fluentd (~> 0.10.48)
font-awesome-rails
haml-rails (~> 0.5.3)
httpclient
@ -81,14 +81,14 @@ GEM
factory_girl_rails (4.4.1)
factory_girl (~> 4.4.0)
railties (>= 3.0.0)
fluentd (0.10.46)
fluentd (0.10.48)
cool.io (>= 1.1.1, < 2.0.0, != 1.2.0)
http_parser.rb (>= 0.5.1, < 0.7.0)
json (>= 1.4.3)
msgpack (>= 0.4.4, < 0.6.0, != 0.5.3, != 0.5.2, != 0.5.1, != 0.5.0)
sigdump (~> 0.2.2)
yajl-ruby (~> 1.0)
font-awesome-rails (4.0.3.1)
font-awesome-rails (4.1.0.0)
railties (>= 3.2, < 5.0)
haml (4.0.5)
tilt

View File

@ -0,0 +1,37 @@
class Fluentd::AgentsController < ApplicationController
before_action :find_fluentd
def show
end
def start
unless @fluentd.agent.start
flash[:error] = t("error.fluentd_start_failed")
end
redirect_to fluentd_agent_path(@fluentd), status: 303 # 303 is change HTTP Verb GET
end
def stop
unless @fluentd.agent.stop
flash[:error] = t("error.fluentd_stop_failed")
end
redirect_to fluentd_agent_path(@fluentd), status: 303 # 303 is change HTTP Verb GET
end
def restart
unless @fluentd.agent.restart
flash[:error] = t("error.fluentd_restart_failed")
end
redirect_to fluentd_agent_path(@fluentd), status: 303 # 303 is change HTTP Verb GET
end
def log
render text: @fluentd.agent.log, content_type: "text/plain"
end
private
def find_fluentd
@fluentd = Fluentd.find(params[:fluentd_id])
end
end

View File

@ -1,32 +0,0 @@
class Fluentd::DaemonsController < ApplicationController
before_action :login_required
before_action :fluentd
def show
end
def start
fluentd.start
render :show
end
def stop
fluentd.stop
render :show
end
def reload
fluentd.reload
render :show
end
def log
render text: fluentd.log, content_type: "text/plain"
end
private
def fluentd
@fluentd ||= Fluentd.new(Rails.root + "tmp" + "fluentd") # TODO
end
end

View File

@ -1,7 +1,47 @@
class FluentdController < ApplicationController
before_action :login_required
before_action :find_fluentd, only: [:edit, :update, :destroy]
def index
@daemons = [Fluentd.new(Rails.root + "tmp" + "fluentd")] # TODO
@fluentds = Fluentd.all
end
def new
@fluentd = Fluentd.new(Fluentd::Agent::Fluentd::DEFAULT_OPTIONS) # TODO: not fluentd type
end
def create
@fluentd = Fluentd.new(fluentd_params)
unless @fluentd.save
return render :new
end
redirect_to fluentd_index_path
end
def edit
end
def update
# TODO: should restart if changed file path? or just do "dirty" flagged?
@fluentd.update_attributes(fluentd_params)
unless @fluentd.save
return render :edit
end
redirect_to fluentd_index_path
end
def destroy
@fluentd.agent.stop if @fluentd.agent.running?
@fluentd.destroy
redirect_to fluentd_index_path
end
private
def find_fluentd
@fluentd = Fluentd.find(params[:id])
end
def fluentd_params
params.require(:fluentd).permit(:log_file, :pid_file, :config_file, :variant)
end
end

View File

@ -1,2 +0,0 @@
module Fluentd::DaemonsHelper
end

View File

@ -1,109 +1,64 @@
Bundler.require(:default, :development)
class Fluentd < ActiveRecord::Base
before_validation :expand_paths
validates :variant, inclusion: { in: proc { Fluentd.variants } }
validates :log_file, presence: true
validates :pid_file, presence: true
validates :config_file, presence: true
validate :validate_permissions
require 'fluent/log'
require 'fluent/env'
require 'fluent/version'
require 'fluent/supervisor'
class Fluentd
attr_reader :root_dir
def initialize(root_dir)
@root_dir = root_dir
FileUtils.mkdir_p @root_dir
def self.variants
%w(fluentd) # TODO:
end
def pid_file
File.join(root_dir, "fluentd.pid")
def fluentd?
variant == "fluentd"
end
def pid
return unless File.exists?(pid_file)
File.read(pid_file)
def td_agent?
variant == "td-agent"
end
def log_file
File.join(root_dir, "fluentd.log")
end
def config_file
file = File.join(root_dir, "fluentd.conf")
unless File.exists?(file)
File.open(file, "w") {|f| f.write "<source>\ntype forward\n</source>" } # TODO
end
file
end
def plugin_dir
dir = File.join(root_dir, "fluentd", "plugins")
unless Dir.exist?(dir)
FileUtils.mkdir_p(dir)
end
dir
end
def options
# TODO: https://github.com/fluent/fluentd/pull/315
{
:config_path => Fluent::DEFAULT_CONFIG_PATH,
:plugin_dirs => [Fluent::DEFAULT_PLUGIN_DIR],
:log_level => Fluent::Log::LEVEL_INFO,
:log_path => nil,
:daemonize => false,
:libs => [],
:setup_path => nil,
:chuser => nil,
:chgroup => nil,
:suppress_interval => 0,
:suppress_repeated_stacktrace => false,
:use_v1_config => false,
}.merge({
:use_v1_config => true,
:plugin_dirs => [plugin_dir],
:config_path => config_file,
:daemonize => pid_file,
:log_path => log_file,
:log_level => Fluent::Log::LEVEL_INFO,
def agent
klass = variant.underscore.camelize
@agent ||= Agent.const_get(klass).new({
:pid_file => pid_file,
:log_file => log_file,
:config_file => config_file,
})
end
def running?
pid && system("/bin/kill -0 #{pid}", :out => File::NULL, :err => File::NULL)
def expand_paths
%w(pid_file log_file config_file).each do |column|
path = send(column)
next if path.blank?
self.send("#{column}=", File.expand_path(path))
end
end
def start
return if running?
spawn("bundle exec fluentd #{options_to_argv(options)}") # TODO
def validate_permissions
%w(pid_file log_file config_file).each do |column|
check_permission(column)
end
end
def stop
return unless running?
system("/bin/kill -TERM #{pid}")
File.unlink(pid_file)
end
def check_permission(column)
path = send(column)
return if path.blank? # if empty, presence: true will catch it
if File.exist?(path)
if File.directory?(path)
errors.add(column, :is_a_directory)
end
def reload
return unless running?
system("/bin/kill -HUP #{pid}")
end
def log
File.read log_file # TODO: large log file
end
def config
::Fluentd::Configuration.new(config_file)
end
private
def options_to_argv(options)
argv = ""
argv << " --use-v1-config" if options[:use_v1_config]
argv << " -c #{options[:config_path]}" if options[:config_path].present?
argv << " -p #{options[:plugin_dir].first}" if options[:plugin_dir].present?
argv << " -d #{options[:daemonize]}" if options[:daemonize].present?
argv << " -o #{options[:log_path]}" if options[:log_path].present?
argv
unless File.writable?(path)
errors.add(column, :lack_write_permission)
end
unless File.readable?(path)
errors.add(column, :lack_read_permission)
end
else
unless File.writable?(File.dirname(path))
errors.add(column, :lack_write_permission)
end
end
end
end

View File

@ -0,0 +1,28 @@
require 'fluent/log'
require 'fluent/env'
require 'fluent/version'
require 'fluent/supervisor'
require "fluentd/agent/common"
require "fluentd/agent/fluentd"
require "fluentd/agent/td_agent"
require "fluentd/agent/remote"
class Fluentd
class Agent
# pidfile
# td-agent: /var/run/td-agent/td-agent.pid
# - https://github.com/treasure-data/td-agent/blob/master/td-agent.logrotate#L10
# - https://github.com/treasure-data/td-agent/blob/master/debian/td-agent.init#L25
# fluentd: nothing (or --daemon PIDFILE)
#
# logfile
# td-agent: /var/log/td-agent/td-agent.log
# - https://github.com/treasure-data/td-agent/blob/master/debian/td-agent.init#L28
# fluentd: stdout (or --log LOGFILE)
#
# config file
# td-agent: /etc/td-agent/td-agent.conf
# - https://github.com/treasure-data/td-agent/blob/master/debian/td-agent.postinst#L69
# fluentd: /etc/fluent/fluent.conf (by fluentd -s)
end
end

View File

@ -0,0 +1,62 @@
# pidfile
# td-agent: /var/run/td-agent/td-agent.pid
# - https://github.com/treasure-data/td-agent/blob/master/td-agent.logrotate#L10
# - https://github.com/treasure-data/td-agent/blob/master/debian/td-agent.init#L25
# fluentd: nothing (or --daemon PIDFILE)
#
# logfile
# td-agent: /var/log/td-agent/td-agent.log
# - https://github.com/treasure-data/td-agent/blob/master/debian/td-agent.init#L28
# fluentd: stdout (or --log LOGFILE)
#
# config file
# td-agent: /etc/td-agent/td-agent.conf
# - https://github.com/treasure-data/td-agent/blob/master/debian/td-agent.postinst#L69
# fluentd: /etc/fluent/fluent.conf (by fluentd -s)
class Fluentd
class Agent
module Common
attr_reader :extra_options
def initialize(options = {})
@extra_options = options
end
def pid
return unless File.exists?(pid_file)
File.read(pid_file).to_i rescue nil
end
def wait_process_starting_seconds
10.seconds # wait time for fluentd pidfile created
end
def running?
pid && Process.kill(0, pid)
end
def log
File.read(log_file) # TODO: large log file
end
def pid_file
extra_options[:pid_file] || self.class.default_options[:pid_file]
end
def log_file
extra_options[:log_file] || self.class.default_options[:log_file]
end
def config_file
extra_options[:config_file] || self.class.default_options[:config_file]
end
%w(start stop restart).each do |method|
define_method(method) do
raise NotImplementedError
end
end
end
end
end

View File

@ -0,0 +1,77 @@
class Fluentd
class Agent
class Fluentd
include Common
def self.default_options
{
:pid_file => "/var/run/fluent.pid",
:log_file => "/var/log/fluent.log",
:config_file => "/etc/fluent/fluent.conf",
}
end
def options_to_argv
argv = ""
argv << " --use-v1-config"
argv << " -c #{config_file}"
argv << " -d #{pid_file}"
argv << " -o #{log_file}"
argv
end
def start
return true if running?
if validate_fluentd_options
actual_start
end
end
def stop
return true unless running?
actual_stop
end
def restart
return false unless running?
actual_restart
end
private
def validate_fluentd_options
system("bundle exec fluentd --dry-run #{options_to_argv}")
end
def actual_start
spawn("bundle exec fluentd #{options_to_argv}")
wait_starting
end
def actual_stop
if Process.kill(:TERM, pid)
File.unlink(pid_file)
true
end
end
def actual_restart
Process.kill(:HUP, pid)
end
def wait_starting
begin
timeout(wait_process_starting_seconds) do
loop do
break if pid && Process.kill(0, pid)
sleep 0.01
end
end
true
rescue TimeoutError
false
end
end
end
end
end

View File

@ -0,0 +1,7 @@
class Fluentd
class Agent
class Remote # TODO
include Common
end
end
end

View File

@ -0,0 +1,29 @@
class Fluentd
class Agent
class TdAgent
include Common
def self.default_options
{
:pid_file => "/var/run/td-agent/td-agent.pid",
:log_file => "/var/log/td-agent/td-agent.log",
:config_file => "/etc/td-agent/td-agent.conf",
}
end
def start
system('/etc/init.d/td-agent start')
end
def stop
system('/etc/init.d/td-agent stop')
end
def restart
# NOTE: td-agent has no reload command
# https://github.com/treasure-data/td-agent/blob/master/debian/td-agent.init#L156
system('/etc/init.d/td-agent restart')
end
end
end
end

View File

@ -86,6 +86,7 @@ class Plugin
end
def self.installed
return [] unless File.exist?(gemfile_path)
File.read(gemfile_path).scan(/"(.*?)", "(.*?)"/).map do |plugin|
new(gem_name: plugin[0], version: plugin[1])
end

View File

@ -0,0 +1,18 @@
%div.col-lg-6
- @fluentd.errors.full_messages.each do |e|
%div.alert.alert-danger= e
= form_for(:fluentd, url: url, method: method) do |f|
%div.form-group
= f.label :variant
= f.select :variant, Fluentd.variants
%div.form-group
= f.label :pid_file
= f.text_field :pid_file, class: "form-control"
%div.form-group
= f.label :log_file
= f.text_field :log_file, class: "form-control"
%div.form-group
= f.label :config_file
= f.text_field :config_file, class: "form-control"
= f.submit btn, class: "btn btn-primary"

View File

@ -0,0 +1,13 @@
- page_title t('.page_title', label: "##{@fluentd.id}")
- if flash[:error]
%div.alert.alert-danger= flash[:error]
%h4
= @fluentd.agent.running? ? t(".running") : t(".stopped")
= link_to t(".start"), start_fluentd_agent_path(@fluentd), method: :put
= link_to t(".stop"), stop_fluentd_agent_path(@fluentd), method: :put
= link_to t(".restart"), restart_fluentd_agent_path(@fluentd), method: :put
= link_to t(".log"), log_fluentd_agent_path(@fluentd)
TODO: config

View File

@ -1,7 +0,0 @@
%h1
= @fluentd.running? ? "running" : "stopped"
= link_to "start", start_fluentd_daemon_path(id: 1), method: :put, remote: true
= link_to "stop", stop_fluentd_daemon_path(id: 1), method: :put, remote: true
= link_to "reload", reload_fluentd_daemon_path(id: 1), method: :put, remote: true
= link_to "log", log_fluentd_daemon_path(id: 1)

View File

@ -0,0 +1,3 @@
- page_title t('.page_title')
= render partial: "form", locals: { btn: t(".update"), url: fluentd_path(@fluentd), method: :patch }

View File

@ -1,2 +1,14 @@
- @daemons.each do |d|
= link_to d, fluentd_daemon_path(fluentd_id: 1) # TODO
- page_title t('.page_title')
%p= link_to icon('fa-plus') << " " << t(".new"), new_fluentd_path
- @fluentds.each do |d|
%div.col-lg-6
%div.panel.panel-default
%div.panel-heading
%h4
= "fluentd ##{d.id}"
= link_to t(".edit"), edit_fluentd_path(d)
= link_to t(".destroy"), fluentd_path(d), method: :delete
%div.panel-body
= link_to t(".operation"), fluentd_agent_path(d) # TODO

View File

@ -0,0 +1,3 @@
- page_title t('.page_title')
= render partial: "form", locals: { btn: t(".create"), url: fluentd_index_path, method: :post }

View File

@ -2,6 +2,14 @@
<li>
<%= link_to_other icon("fa-dashboard fa-fw") << " Dashboard", root_path %>
</li>
<li>
<%= link_to_other icon("fa-puzzle-piece fa-fw") << " fluentd", fluentd_index_path %>
<ul class="nav nav-second-level">
<li>
<%= link_to_other t("terms.new"), new_fluentd_path %>
</li>
</ul>
</li>
<li>
<%= link_to_other icon("fa-cogs fa-fw") << " " << t('terms.plugins') << icon('fa pull-right fa-caret-down'), plugins_path %>
<ul class="nav nav-second-level">

View File

@ -13,6 +13,7 @@ require "sprockets/railtie"
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
# these gems are not required by Bundler.require
require "sass"
require "haml-rails"
require "jquery-rails"
require "sucker_punch"

View File

@ -16,6 +16,11 @@ ja:
fluent_version: "fluentd %{version}"
no_alert: なし
update_password: パスワード更新
create: 作成
update: 更新
edit: 編集
destroy: 削除
new: 新規作成
plugins:
common: &plugin_common
@ -45,6 +50,32 @@ ja:
<<: *terms
page_title: ユーザー管理
fluentd: &fluentd
common: &fluentd_common
<<: *terms
start: 開始
stop: 停止
restart: 再起動
log: ログ
stopped: 停止中
running: 稼働中
operation: プロセス詳細
form:
<<: *fluentd_common
index:
<<: *fluentd_common
page_title: fluentd
new:
<<: *fluentd_common
page_title: fluentd | 追加
edit:
<<: *fluentd_common
page_title: fluentd | 編集
agents:
show:
<<: *fluentd_common
page_title: "fluentd %{label}"
misc:
common: &misc_common
<<: *terms
@ -61,11 +92,17 @@ ja:
error:
login_failed: ログインに失敗しました。
fluentd_start_failed: fluentdの起動に失敗しました。
fluentd_stop_failed: fluentdの停止に失敗しました。
fluentd_restart_failed: fluentdの再起動に失敗しました。
activerecord:
errors:
messages:
wrong_password: が違います
lack_read_permission: の読み込み権限がありません
lack_write_permission: の書き込み権限がありません
is_a_directory: はディレクトリです。ファイルを指定してください
models:
user: user #g
@ -78,3 +115,8 @@ ja:
current_password: 現在のパスワード
password: パスワード
password_confirmation: パスワード(確認)
fluentd:
log_file: ログファイル
pid_file: PIDファイル
config_file: 設定ファイル
variant: タイプ

View File

@ -1,11 +1,11 @@
Rails.application.routes.draw do
root "fluentd#index" # TODO: change to dashboard
resources :fluentd, only: [:index] do
resource :daemon, only: [:show], module: :fluentd do
resources :fluentd do
resource :agent, only: [:show], module: :fluentd do
put "start"
put "stop"
put "reload"
put "restart"
get "log"
end
resource :setting, only: [:show, :edit, :update], module: :fluentd do

View File

@ -0,0 +1,12 @@
class CreateFluentds < ActiveRecord::Migration
def change
create_table :fluentds do |t|
t.string :variant, null: false # fluentd, td-agent, or remote
t.string :pid_file
t.string :log_file
t.string :config_file
t.timestamps
end
end
end

View File

@ -11,7 +11,16 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20140522023140) do
ActiveRecord::Schema.define(version: 20140522055753) do
create_table "fluentds", force: true do |t|
t.string "variant", null: false
t.string "pid_file"
t.string "log_file"
t.string "config_file"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "login_tokens", force: true do |t|
t.string "token_id", null: false

View File

@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
spec.require_paths = ["lib"]
spec.add_dependency "fluentd", "0.10.46"
spec.add_dependency "fluentd", "~> 0.10.48"
spec.add_dependency 'rails', '4.1.1'
spec.add_dependency 'sucker_punch', "~> 1.0.5"
spec.add_dependency 'i18n_generators', '1.2.1'

View File

@ -0,0 +1,8 @@
FactoryGirl.define do
factory :fluentd do
variant "fluentd"
log_file (Rails.root + "tmp/fluentd-test/fluentd.log").to_s
pid_file (Rails.root + "tmp/fluentd-test/fluentd.pid").to_s
config_file (Rails.root + "tmp/fluentd-test/fluentd.conf").to_s
end
end

View File

@ -1,15 +0,0 @@
require 'spec_helper'
# Specs in this file have access to a helper object that includes
# the MiscsHelper. For example:
#
# describe MiscsHelper do
# describe "string concat" do
# it "concats two strings with spaces" do
# expect(helper.concat_strings("this","that")).to eq("this that")
# end
# end
# end
describe MiscsHelper do
pending "add some examples to (or delete) #{__FILE__}"
end

View File

@ -0,0 +1,119 @@
require 'spec_helper'
describe Fluentd::Agent do
shared_examples_for "Agent has common behavior" do |klass|
describe "#extra_options" do
context "blank" do
let(:options) { {} }
it { instance.pid_file.should == described_class.default_options[:pid_file] }
it { instance.log_file.should == described_class.default_options[:log_file] }
it { instance.config_file.should == described_class.default_options[:config_file] }
end
context "given" do
let(:options) do
{
:pid_file => pid_file,
:log_file => log_file,
:config_file => config_file,
}
end
let(:pid_file) { "pid" }
let(:log_file) { "log" }
let(:config_file) { "config" }
it { instance.pid_file.should == pid_file }
it { instance.log_file.should == log_file }
it { instance.config_file.should == config_file }
end
end
end
let(:instance) { described_class.new(options) }
let(:options) { {} }
describe "Fluentd" do
let(:described_class) { Fluentd::Agent::Fluentd } # override nested described_class behavior as https://github.com/rspec/rspec-core/issues/1114
it_should_behave_like "Agent has common behavior"
describe "#options_to_argv" do
subject { instance.options_to_argv }
it { should include("-c #{instance.config_file}") }
it { should include("-d #{instance.pid_file}") }
it { should include("-o #{instance.log_file}") }
it { should include("--use-v1-config") }
end
describe "#start" do
before { instance.stub(:running?).and_return { running } }
context "running" do
let(:running) { true }
after { instance.start }
it { instance.should_not_receive(:validate_fluentd_options) }
end
context "not running" do
let(:running) { false }
after { instance.start }
it { instance.should_receive(:validate_fluentd_options) }
context "validate_fluentd_options success" do
before { instance.stub(:validate_fluentd_options).and_return { true } }
it { instance.should_receive(:actual_start) }
end
context "validate_fluentd_options fail" do
before { instance.stub(:validate_fluentd_options).and_return { false } }
it { instance.should_not_receive(:actual_start) }
end
end
end
describe "#stop" do
before { instance.stub(:running?).and_return { running } }
context "running" do
let(:running) { true }
after { instance.stop }
it { instance.should_receive(:actual_stop) }
end
context "not running" do
let(:running) { false }
after { instance.stop }
it { instance.should_not_receive(:actual_stop) }
end
end
describe "#restart" do
before { instance.stub(:running?).and_return { running } }
context "running" do
let(:running) { true }
after { instance.restart }
it { instance.should_receive(:actual_restart) }
end
context "not running" do
let(:running) { false }
after { instance.restart }
it { instance.should_not_receive(:actual_restart) }
end
end
end
describe "TdAgent" do
let(:described_class) { Fluentd::Agent::TdAgent } # override nested described_class behavior as https://github.com/rspec/rspec-core/issues/1114
it_should_behave_like "Agent has common behavior"
end
end

127
spec/models/fluentd_spec.rb Normal file
View File

@ -0,0 +1,127 @@
require 'spec_helper'
describe Fluentd do
shared_examples_for "path permission" do |column|
let(:path) { fluentd.send(column) }
subject do
fluentd.check_permission(column)
fluentd.errors
end
context "file exists" do
before { FileUtils.touch(path) }
after { FileUtils.chmod(0755, path) }
context "writable" do
before { FileUtils.chmod(0600, path) }
it { should be_blank }
end
context "not writable" do
before { FileUtils.chmod(0400, path) }
it { should_not be_blank }
it { subject.get(column).should include(I18n.t('activerecord.errors.messages.lack_write_permission')) }
end
context "not readable" do
before { FileUtils.chmod(0200, path) }
it { should_not be_blank }
it { subject.get(column).should include(I18n.t('activerecord.errors.messages.lack_read_permission')) }
end
context "is directory" do
before { fluentd.send("#{column}=", Rails.root + "tmp") }
it { should_not be_blank }
it { subject.get(column).should include(I18n.t('activerecord.errors.messages.is_a_directory')) }
end
end
context "file not exists" do
let(:dir) { File.dirname(path) }
before { FileUtils.rm path }
after { FileUtils.chmod_R(0755, dir) }
context "writable" do
before { FileUtils.chmod(0700, dir) }
it { should be_blank }
end
context "not writable" do
before { FileUtils.chmod(0500, dir) }
it { should_not be_blank }
it { subject.get(column).should include(I18n.t('activerecord.errors.messages.lack_write_permission')) }
end
end
end
let(:fluentd) { FactoryGirl.build(:fluentd) }
describe "#valid?" do
before do
%w(pid_file log_file config_file).each do |column|
FileUtils.mkdir_p File.dirname(fluentd.send(column))
FileUtils.touch fluentd.send(column)
end
end
subject { fluentd }
describe "variant" do
before { fluentd.variant = variant }
context "fluentd" do
let(:variant) { "fluentd" }
it { should be_valid }
end
context "foobar (not declared in Fluentd.variants)" do
let(:variant) { "foobar" }
it { should_not be_valid }
end
end
describe "pid_file" do
it_should_behave_like "path permission", :pid_file
end
describe "log_file" do
it_should_behave_like "path permission", :log_file
end
describe "config_file" do
it_should_behave_like "path permission", :config_file
end
end
describe "variant" do
before { fluentd.variant = variant }
context "= fluentd" do
let(:variant) { "fluentd" }
it { fluentd.should be_fluentd }
it { fluentd.should_not be_td_agent }
end
context "= td-agent" do
let(:variant) { "td-agent" }
it { fluentd.should_not be_fluentd }
it { fluentd.should be_td_agent }
end
end
describe "#agent" do
before { fluentd.variant = variant }
subject { fluentd.agent }
context "fluentd" do
let(:variant) { "fluentd" }
it { should be_instance_of(Fluentd::Agent::Fluentd) }
end
context "td-agent" do
let(:variant) { "td-agent" }
it { should be_instance_of(Fluentd::Agent::TdAgent) }
end
end
end

View File

@ -64,12 +64,4 @@ RSpec.configure do |config|
config.after(:each) do
DatabaseCleaner.clean
end
config.before(:each) do
system('sync') if ENV["CIRCLECI"] # file operations are unstable on Circle CI
end
config.after(:each) do
system('sync') if ENV["CIRCLECI"] # file operations are unstable on Circle CI
end
end