diff --git a/test/factories/fluentd.rb b/test/factories/fluentd.rb
new file mode 100644
index 0000000..aff33b9
--- /dev/null
+++ b/test/factories/fluentd.rb
@@ -0,0 +1,11 @@
+FactoryBot.define do
+ factory :fluentd do
+ dir = Rails.root.join("tmp/fluentd-test").to_s
+ FileUtils.mkdir_p(dir)
+
+ variant "fluentd_gem"
+ log_file dir + "/fluentd.log"
+ pid_file dir + "/fluentd.pid"
+ config_file dir + "/fluentd.conf"
+ end
+end
diff --git a/test/factories/plugins.rb b/test/factories/plugins.rb
new file mode 100644
index 0000000..010699b
--- /dev/null
+++ b/test/factories/plugins.rb
@@ -0,0 +1,8 @@
+# Read about factories at https://github.com/thoughtbot/factory_bot
+
+FactoryBot.define do
+ factory :plugin do
+ gem_name "fluent-plugin-dummy"
+ version "1.2.3"
+ end
+end
diff --git a/test/factories/user.rb b/test/factories/user.rb
new file mode 100644
index 0000000..e5f5e63
--- /dev/null
+++ b/test/factories/user.rb
@@ -0,0 +1,6 @@
+FactoryBot.define do
+ factory :user do
+ name "admin"
+ password "changeme"
+ end
+end
diff --git a/test/fixtures/error0.log b/test/fixtures/error0.log
new file mode 100644
index 0000000..24b949c
--- /dev/null
+++ b/test/fixtures/error0.log
@@ -0,0 +1,12 @@
+foo
+bar
+baz
+1
+2
+3
+4
+5
+6
+10
+11
+12
diff --git a/test/fixtures/error2.log b/test/fixtures/error2.log
new file mode 100644
index 0000000..86aa353
--- /dev/null
+++ b/test/fixtures/error2.log
@@ -0,0 +1,130 @@
+2014-05-27 10:54:37 +0900 [info]: starting fluentd-0.10.48
+2014-05-27 10:54:37 +0900 [info]: reading config file path="/tmp/2.conf"
+2014-05-27 10:54:37 +0900 [info]: gem 'fluentd' version '0.10.48'
+2014-05-27 10:54:37 +0900 [info]: using configuration file:
+
+ type forward
+ port 24224
+
+
+ type monitor_agent
+ port 24220
+
+
+ type http
+ port 9880
+
+
+ type debug_agent
+ port 24230
+
+
+2014-05-27 10:54:37 +0900 [info]: adding source type="forward"
+2014-05-27 10:54:37 +0900 [info]: adding source type="monitor_agent"
+2014-05-27 10:54:37 +0900 [info]: adding source type="http"
+2014-05-27 10:54:37 +0900 [info]: adding source type="debug_agent"
+2014-05-27 10:54:37 +0900 [info]: listening fluent socket on 0.0.0.0:24224
+2014-05-27 10:54:37 +0900 [error]: unexpected error error_class=Errno::EADDRINUSE error=#
+ 2014-05-27 10:54:37 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/cool.io-1.2.4/lib/cool.io/server.rb:57:in `initialize'
+ 2014-05-27 10:54:37 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/cool.io-1.2.4/lib/cool.io/server.rb:57:in `new'
+ 2014-05-27 10:54:37 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/cool.io-1.2.4/lib/cool.io/server.rb:57:in `initialize'
+ 2014-05-27 10:54:37 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/fluentd-0.10.48/lib/fluent/plugin/in_forward.rb:76:in `new'
+ 2014-05-27 10:54:37 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/fluentd-0.10.48/lib/fluent/plugin/in_forward.rb:76:in `listen'
+ 2014-05-27 10:54:37 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/fluentd-0.10.48/lib/fluent/plugin/in_forward.rb:47:in `start'
+ 2014-05-27 10:54:37 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/fluentd-0.10.48/lib/fluent/engine.rb:260:in `block in start'
+ 2014-05-27 10:54:37 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/fluentd-0.10.48/lib/fluent/engine.rb:259:in `each'
+ 2014-05-27 10:54:37 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/fluentd-0.10.48/lib/fluent/engine.rb:259:in `start'
+ 2014-05-27 10:54:37 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/fluentd-0.10.48/lib/fluent/engine.rb:206:in `run'
+ 2014-05-27 10:54:37 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/fluentd-0.10.48/lib/fluent/supervisor.rb:417:in `run_engine'
+ 2014-05-27 10:54:37 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/fluentd-0.10.48/lib/fluent/supervisor.rb:116:in `block in start'
+ 2014-05-27 10:54:37 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/fluentd-0.10.48/lib/fluent/supervisor.rb:229:in `call'
+ 2014-05-27 10:54:37 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/fluentd-0.10.48/lib/fluent/supervisor.rb:229:in `main_process'
+ 2014-05-27 10:54:37 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/fluentd-0.10.48/lib/fluent/supervisor.rb:204:in `block in supervise'
+ 2014-05-27 10:54:37 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/fluentd-0.10.48/lib/fluent/supervisor.rb:203:in `fork'
+ 2014-05-27 10:54:37 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/fluentd-0.10.48/lib/fluent/supervisor.rb:203:in `supervise'
+ 2014-05-27 10:54:37 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/fluentd-0.10.48/lib/fluent/supervisor.rb:109:in `start'
+ 2014-05-27 10:54:37 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/fluentd-0.10.48/lib/fluent/command/fluentd.rb:160:in `'
+ 2014-05-27 10:54:37 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/fluentd-0.10.48/bin/fluentd:6:in `require'
+ 2014-05-27 10:54:37 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/fluentd-0.10.48/bin/fluentd:6:in `'
+ 2014-05-27 10:54:37 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/bin/fluentd:23:in `load'
+ 2014-05-27 10:54:37 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/bin/fluentd:23:in `'
+2014-05-27 10:54:37 +0900 [info]: shutting down fluentd
+2014-05-27 10:54:37 +0900 [info]: process finished code=0
+2014-05-27 10:54:37 +0900 [warn]: process died within 1 second. exit.
+2014-05-27 11:28:10 +0900 [info]: reading config file path="/tmp/2.conf"
+2014-05-27 11:28:10 +0900 [info]: gem 'fluentd' version '0.10.48'
+2014-05-27 11:28:10 +0900 [info]: using configuration file:
+
+ type forward
+ port 24224
+
+
+ type monitor_agent
+ port 24220
+
+
+ type http
+ port 9880
+
+
+ type debug_agent
+ port 24230
+
+
+2014-05-27 11:28:10 +0900 [info]: adding source type="forward"
+2014-05-27 11:28:10 +0900 [info]: adding source type="monitor_agent"
+2014-05-27 11:28:10 +0900 [info]: adding source type="http"
+2014-05-27 11:28:10 +0900 [info]: adding source type="debug_agent"
+2014-05-27 11:28:12 +0900 [info]: starting fluentd-0.10.48
+2014-05-27 11:28:12 +0900 [info]: reading config file path="/tmp/2.conf"
+2014-05-27 11:28:12 +0900 [info]: gem 'fluentd' version '0.10.48'
+2014-05-27 11:28:12 +0900 [info]: using configuration file:
+
+ type forward
+ port 24224
+
+
+ type monitor_agent
+ port 24220
+
+
+ type http
+ port 9880
+
+
+ type debug_agent
+ port 24230
+
+
+2014-05-27 11:28:12 +0900 [info]: adding source type="forward"
+2014-05-27 11:28:12 +0900 [info]: adding source type="monitor_agent"
+2014-05-27 11:28:12 +0900 [info]: adding source type="http"
+2014-05-27 11:28:12 +0900 [info]: adding source type="debug_agent"
+2014-05-27 11:28:12 +0900 [info]: listening fluent socket on 0.0.0.0:24224
+2014-05-27 11:28:12 +0900 [error]: unexpected error error_class=Errno::EADDRINUSE error=#
+ 2014-05-27 11:28:12 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/cool.io-1.2.4/lib/cool.io/server.rb:57:in `initialize'
+ 2014-05-27 11:28:12 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/cool.io-1.2.4/lib/cool.io/server.rb:57:in `new'
+ 2014-05-27 11:28:12 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/cool.io-1.2.4/lib/cool.io/server.rb:57:in `initialize'
+ 2014-05-27 11:28:12 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/fluentd-0.10.48/lib/fluent/plugin/in_forward.rb:76:in `new'
+ 2014-05-27 11:28:12 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/fluentd-0.10.48/lib/fluent/plugin/in_forward.rb:76:in `listen'
+ 2014-05-27 11:28:12 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/fluentd-0.10.48/lib/fluent/plugin/in_forward.rb:47:in `start'
+ 2014-05-27 11:28:12 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/fluentd-0.10.48/lib/fluent/engine.rb:260:in `block in start'
+ 2014-05-27 11:28:12 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/fluentd-0.10.48/lib/fluent/engine.rb:259:in `each'
+ 2014-05-27 11:28:12 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/fluentd-0.10.48/lib/fluent/engine.rb:259:in `start'
+ 2014-05-27 11:28:12 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/fluentd-0.10.48/lib/fluent/engine.rb:206:in `run'
+ 2014-05-27 11:28:12 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/fluentd-0.10.48/lib/fluent/supervisor.rb:417:in `run_engine'
+ 2014-05-27 11:28:12 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/fluentd-0.10.48/lib/fluent/supervisor.rb:116:in `block in start'
+ 2014-05-27 11:28:12 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/fluentd-0.10.48/lib/fluent/supervisor.rb:229:in `call'
+ 2014-05-27 11:28:12 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/fluentd-0.10.48/lib/fluent/supervisor.rb:229:in `main_process'
+ 2014-05-27 11:28:12 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/fluentd-0.10.48/lib/fluent/supervisor.rb:204:in `block in supervise'
+ 2014-05-27 11:28:12 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/fluentd-0.10.48/lib/fluent/supervisor.rb:203:in `fork'
+ 2014-05-27 11:28:12 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/fluentd-0.10.48/lib/fluent/supervisor.rb:203:in `supervise'
+ 2014-05-27 11:28:12 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/fluentd-0.10.48/lib/fluent/supervisor.rb:109:in `start'
+ 2014-05-27 11:28:12 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/fluentd-0.10.48/lib/fluent/command/fluentd.rb:160:in `'
+ 2014-05-27 11:28:12 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/fluentd-0.10.48/bin/fluentd:6:in `require'
+ 2014-05-27 11:28:12 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/fluentd-0.10.48/bin/fluentd:6:in `'
+ 2014-05-27 11:28:12 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/bin/fluentd:23:in `load'
+ 2014-05-27 11:28:12 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/bin/fluentd:23:in `'
+2014-05-27 11:28:12 +0900 [info]: shutting down fluentd
+2014-05-27 11:28:12 +0900 [info]: process finished code=0
+2014-05-27 11:28:12 +0900 [warn]: process died within 1 second. exit.
diff --git a/test/fixtures/error3.log b/test/fixtures/error3.log
new file mode 100644
index 0000000..d72f006
--- /dev/null
+++ b/test/fixtures/error3.log
@@ -0,0 +1,7 @@
+2014-05-27 10:54:37 +0900 [info]: listening fluent socket on 0.0.0.0:24224
+2014-05-27 10:54:37 +0900 [error]: unexpected error error_class=Errno::EADDRINUSE error=#
+2014-05-27 10:55:40 +0900 [error]: unexpected error error_class=Errno::EADDRINUSE error=#
+ 2014-05-27 10:55:40 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/cool.io-1.2.4/lib/cool.io/server.rb:57:in `initialize'
+ 2014-05-27 10:55:40 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/cool.io-1.2.4/lib/cool.io/server.rb:57:in `new'
+2014-05-27 11:28:12 +0900 [error]: unexpected error error_class=Errno::EADDRINUSE error=#
+ 2014-05-27 11:28:12 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/cool.io-1.2.4/lib/cool.io/server.rb:57:in `initialize'
diff --git a/test/fixtures/error4.log b/test/fixtures/error4.log
new file mode 100644
index 0000000..a427df3
--- /dev/null
+++ b/test/fixtures/error4.log
@@ -0,0 +1 @@
+2014-05-27 10:54:37 +0900 [info]: listening fluent socket on 0.0.0.0:24224
diff --git a/test/fixtures/multiline_example.log b/test/fixtures/multiline_example.log
new file mode 100644
index 0000000..a6e4ef2
--- /dev/null
+++ b/test/fixtures/multiline_example.log
@@ -0,0 +1,5 @@
+2013-3-03 14:27:33 [main] INFO Main - Start
+2013-3-03 14:27:33 [main] ERROR Main - Exception
+javax.management.RuntimeErrorException: null
+ at Main.main(Main.java:16) ~[bin/:na]
+2013-3-03 14:27:33 [main] INFO Main - End
diff --git a/test/models/fluent_gem_test.rb b/test/models/fluent_gem_test.rb
new file mode 100644
index 0000000..f417fa3
--- /dev/null
+++ b/test/models/fluent_gem_test.rb
@@ -0,0 +1,76 @@
+require "test_helper"
+
+class FluentGemTest < ActiveSupport::TestCase
+
+ data("no arguments" => [],
+ "1 argument" => ["plugin-foo"],
+ "2 arguments" => ["plugin-foo", "--no-document"])
+ test "install" do |args|
+ if args.empty?
+ mock(FluentGem).run("install")
+ FluentGem.install
+ else
+ mock(FluentGem).run("install", *args)
+ FluentGem.install(*args)
+ end
+ end
+
+ data("no arguments" => [],
+ "1 argument" => ["plugin-foo"],
+ "2 arguments" => ["plugin-foo", "--no-document"])
+ test "uninstall" do |args|
+ if args.empty?
+ mock(FluentGem).run("uninstall")
+ FluentGem.uninstall
+ else
+ mock(FluentGem).run("uninstall", *args)
+ FluentGem.uninstall(*args)
+ end
+ end
+
+ data("no list" => "",
+ "some lines" => <<-GEM_LIST.strip_heredoc)
+ dummy (3.3.3)
+ fluent-plugin-foo (0.1.2)
+ more_dummy (0.0.1)
+ GEM_LIST
+ test "list" do |gem_list|
+ stub(FluentGem).gem { "gem" }
+ stub(FluentGem).__double_definition_create__.call(:`, "gem list 2>&1") { gem_list }
+ assert_equal(gem_list.lines.to_a, FluentGem.list)
+ end
+
+ sub_test_case("run") do
+ test "success" do
+ stub(FluentGem).gem { "gem" }
+ args = ["install", "foobar"]
+ stub(FluentGem).system("gem", *args) { true }
+ assert_true(FluentGem.run(*args))
+ end
+
+ test "failure" do
+ stub(FluentGem).gem { "gem" }
+ args = ["install", "foobar"]
+ stub(FluentGem).system("gem", *args) { false }
+ assert_raise(FluentGem::GemError) do
+ FluentGem.run(*args)
+ end
+ end
+ end
+
+ sub_test_case "gem" do
+ test "any instance not setup yet" do
+ assert_equal("fluent-gem", FluentGem.gem)
+ end
+
+ test "fluentd setup" do
+ stub(Fluentd).instance { Fluentd.new(id: nil, variant: "fluentd_gem", log_file: "dummy.log", pid_file: "dummy.pid", config_file: "dummy.conf") }
+ assert_equal("fluent-gem", FluentGem.gem)
+ end
+
+ test "td-agent 3 setup" do
+ stub(Fluentd).instance { Fluentd.new(id: nil, variant: "td_agent", log_file: "dummy.log", pid_file: "dummy.pid", config_file: "dummy.conf") }
+ assert_equal(FluentGem.detect_td_agent_gem, FluentGem.gem)
+ end
+ end
+end
diff --git a/test/models/fluentd_log_test.rb b/test/models/fluentd_log_test.rb
new file mode 100644
index 0000000..b98db4b
--- /dev/null
+++ b/test/models/fluentd_log_test.rb
@@ -0,0 +1,140 @@
+require "test_helper"
+
+class FluentdLogTest < ActiveSupport::TestCase
+ sub_test_case "#read" do
+ setup do
+ @logfile = Rails.root.join("tmp", "dummylog").to_s
+ @log = FluentdLog.new(@logfile)
+ end
+
+ test "compatible with utf-8" do
+ content = "utf8あいう\n"
+ File.write(@logfile, content)
+ assert_equal(content, @log.read)
+ end
+
+ test "incompatible with utf-8" do
+ content = "eucあいう\n".encode('euc-jp').force_encoding('ascii-8bit')
+ File.open(@logfile, "wb") {|file| file.write(content) }
+ assert_equal(content, @log.read)
+ end
+ end
+
+ sub_test_case "#tail" do
+ setup do
+ @logfile = Rails.root.join("tmp", "dummylog").to_s
+ @log = FluentdLog.new(@logfile)
+ File.open(@logfile, "wb") do |file|
+ 5.times do |n|
+ file.puts(n)
+ end
+ end
+ end
+
+ data("tail(5)" => [5, %w(4 3 2 1 0)],
+ "tail(3)" => [3, %w(4 3 2)],
+ "tail(99)" => [99, %w(4 3 2 1 0)])
+ test "5 line log" do |(limit, expected)|
+ assert_equal(@log.tail(limit), expected)
+ end
+ end
+
+ sub_test_case "#logged_errors" do
+ data("have 0 error log" => "error0.log",
+ "have error log" => "error2.log")
+ test "#last_error_message" do |path|
+ logfile = fixture_path(path)
+ log = FluentdLog.new(logfile)
+ if path == "error0.log"
+ assert do
+ log.last_error_message.empty?
+ end
+ else
+ assert_equal(log.last_error_message, log.recent_errors(1).first[:subject])
+ end
+ end
+
+ sub_test_case "#errors_since" do
+ setup do
+ @logged_time = Time.parse("2014-05-27")
+ @now = Time.parse("2014-05-29")
+ Timecop.freeze(@now)
+ end
+
+ teardown do
+ Timecop.return
+ end
+
+ test "have no errors" do
+ log = FluentdLog.new(fixture_path("error0.log"))
+ assert do
+ log.errors_since(100.days.ago).empty?
+ end
+ end
+
+ sub_test_case "have errors" do
+ setup do
+ @log = FluentdLog.new(fixture_path("error2.log"))
+ end
+
+ test "unreachable since" do
+ assert do
+ @log.errors_since(0.days.ago).empty?
+ end
+ end
+
+ test "reachable since" do
+ errors = @log.errors_since(100.days.ago)
+ assert_equal("unexpected error error_class=Errno::EADDRINUSE error=#",
+ errors[0][:subject].slice(/\[error\]: (.+)/, 1))
+ assert do
+ Time.parse(errors[0][:subject]) >= Time.parse(errors[1][:subject])
+ end
+ end
+ end
+ end
+
+ sub_test_case "recent_errors" do
+ test "have 0 error log" do
+ log = FluentdLog.new(fixture_path("error0.log"))
+ assert do
+ log.recent_errors(2).empty?
+ end
+ end
+
+ sub_test_case "have 2 error log" do
+ setup do
+ @log = FluentdLog.new(fixture_path("error2.log"))
+ end
+
+ data("limit=1" => 1,
+ "limit=2" => 2)
+ test "limit" do |limit|
+ assert_equal(limit, @log.recent_errors(limit).length)
+ end
+
+ test "contains stack trace" do
+ errors = @log.recent_errors(2)
+ assert_equal("unexpected error error_class=Errno::EADDRINUSE error=#",
+ errors[0][:subject].slice(/\[error\]: (.+)/, 1))
+ assert do
+ Time.parse(errors[0][:subject]) >= Time.parse(errors[1][:subject])
+ end
+ end
+ end
+
+ sub_test_case "have 3 errors including sequential 2 error log" do
+ test "count 3 errors" do
+ log = FluentdLog.new(fixture_path("error3.log"))
+ errors = log.recent_errors(3)
+ assert_equal(errors[0][:subject].slice(/::EADDRINUSE: (\d) Address already in use/, 1), "3")
+ assert_equal(errors[0][:notes].size, 1)
+ assert_equal(errors[1][:subject].slice(/::EADDRINUSE: (\d) Address already in use/, 1), "2")
+ assert_equal(errors[1][:notes].size, 2)
+ assert_equal(errors[2][:subject].slice(/::EADDRINUSE: (\d) Address already in use/, 1), "1")
+ assert_equal(errors[2][:notes].size, 0)
+ end
+ end
+ end
+ end
+end
diff --git a/test/models/fluentd_test.rb b/test/models/fluentd_test.rb
new file mode 100644
index 0000000..5949822
--- /dev/null
+++ b/test/models/fluentd_test.rb
@@ -0,0 +1,185 @@
+require "test_helper"
+
+class FluentdTest < ActiveSupport::TestCase
+ module PathPermission
+ def self.included(base)
+ base.class_eval do
+ setup do
+ setup_target
+ end
+
+ sub_test_case "file exists" do
+ setup do
+ FileUtils.touch(@path)
+ end
+
+ teardown do
+ FileUtils.rm_f(@path)
+ end
+
+ test "writable" do
+ FileUtils.chmod(0600, @path)
+ @fluentd.check_permission(@column)
+ assert do
+ @fluentd.errors.blank?
+ end
+ end
+
+ test "not writable" do
+ FileUtils.chmod(0400, @path)
+ @fluentd.check_permission(@column)
+ assert do
+ @fluentd.errors.present?
+ end
+ assert_equal(I18n.t('activerecord.errors.messages.lack_write_permission'), @fluentd.errors[@column].first)
+ end
+
+ test "not readable" do
+ FileUtils.chmod(0200, @path)
+ @fluentd.check_permission(@column)
+ assert do
+ @fluentd.errors.present?
+ end
+ assert_equal(I18n.t('activerecord.errors.messages.lack_read_permission'), @fluentd.errors[@column].first)
+ end
+
+ test "is directory" do
+ @fluentd.__send__("#{@column}=", Rails.root + "tmp")
+ @fluentd.check_permission(@column)
+ assert do
+ @fluentd.errors.present?
+ end
+ assert_equal(I18n.t('activerecord.errors.messages.is_a_directory'), @fluentd.errors[@column].first)
+ end
+ end
+
+ sub_test_case "file not exists" do
+ setup do
+ @dir = File.dirname(@path)
+ FileUtils.rm_f(@path)
+ end
+
+ teardown do
+ FileUtils.chmod_R(0755, @dir)
+ end
+
+ test "writable" do
+ FileUtils.chmod(0700, @dir)
+ @fluentd.check_permission(@column)
+ assert do
+ @fluentd.errors.blank?
+ end
+ end
+
+ test "not writable" do
+ FileUtils.chmod(0500, @dir)
+ @fluentd.check_permission(@column)
+ assert do
+ @fluentd.errors.present?
+ end
+ assert_equal(I18n.t('activerecord.errors.messages.lack_write_permission'), @fluentd.errors[@column].first)
+ end
+ end
+ end
+ end
+ end
+
+ setup do
+ @fluentd = FactoryBot.build(:fluentd)
+ end
+
+ teardown do
+ File.unlink(Fluentd.json_path) if File.exist?(Fluentd.json_path)
+ end
+
+ sub_test_case "#valid?" do
+ setup 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
+
+ data("fluentd" => ["fluentd_gem", true],
+ "not declared in Fluentd.variants" => ["foobar", false])
+ test "variant" do |(variant, result)|
+ @fluentd.variant = variant
+ assert_equal(result, @fluentd.valid?)
+ end
+
+ sub_test_case "pid_file" do
+ def setup_target
+ @column = :pid_file
+ @path = @fluentd.pid_file
+ end
+ include PathPermission
+ end
+
+ sub_test_case "log_file" do
+ def setup_target
+ @column = :log_file
+ @path = @fluentd.log_file
+ end
+ include PathPermission
+ end
+
+ sub_test_case "config_file" do
+ def setup_target
+ @column = :config_file
+ @path = @fluentd.config_file
+ end
+ include PathPermission
+ end
+ end
+
+ data("fluentd_gem" => { variant: "fluentd_gem", fluentd_gem?: true },
+ "td-agent" => { variant: "td-agent", fluentd_gem?: false })
+ test "variant" do |data|
+ @fluentd.variant = data[:variant]
+ assert_equal(data[:fluentd_gem?], @fluentd.fluentd_gem?)
+ @fluentd.load_settings_from_agent_default
+ expected = {
+ pid_file: @fluentd.agent.class.default_options[:pid_file],
+ log_file: @fluentd.agent.class.default_options[:log_file],
+ config_file: @fluentd.agent.class.default_options[:config_file]
+ }
+ actual = {
+ pid_file: @fluentd.pid_file,
+ log_file: @fluentd.log_file,
+ config_file: @fluentd.config_file,
+ }
+ assert_equal(expected, actual)
+ end
+
+ data("fluentd_gem" => ["fluentd_gem", Fluentd::Agent::FluentdGem],
+ "td-agent" => ["td-agent", Fluentd::Agent::TdAgent])
+ test "#agent" do |(variant, klass)|
+ @fluentd.variant = variant
+ assert do
+ @fluentd.agent.instance_of?(klass)
+ end
+ end
+
+ sub_test_case "#ensure_default_config_file" do
+ setup do
+ @config_file = Rails.root + "tmp/test.conf"
+ @fluentd.config_file = @config_file
+ end
+
+ test "doesn't exist" do
+ File.unlink(@config_file) if File.exist?(@config_file)
+ @fluentd.save
+ assert do
+ File.exist?(@fluentd.config_file)
+ end
+ end
+
+ test "already exist" do
+ FileUtils.touch(@config_file)
+ @fluentd.save
+ assert do
+ File.exist?(@fluentd.config_file)
+ end
+ end
+ end
+end
diff --git a/test/test_helper.rb b/test/test_helper.rb
new file mode 100644
index 0000000..ab6b45b
--- /dev/null
+++ b/test/test_helper.rb
@@ -0,0 +1,14 @@
+ENV['RAILS_ENV'] ||= 'test'
+require_relative '../config/environment'
+require 'test/unit/rails/test_help'
+require 'test/unit/rr'
+
+class ActiveSupport::TestCase
+ # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
+ #fixtures :all
+
+ # Add more helper methods to be used by all tests here...
+ def fixture_path(fixture_name)
+ Rails.root.join("test/fixtures", fixture_name).to_s
+ end
+end