fluentd-ui 1.0.0.beta.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of fluentd-ui might be problematic. Click here for more details.

Files changed (136) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog.md +24 -0
  3. data/Gemfile +5 -3
  4. data/Gemfile.lock +88 -75
  5. data/README.md +11 -0
  6. data/Rakefile +1 -1
  7. data/app/javascript/packs/aws_credential.js +1 -1
  8. data/app/javascript/packs/in_tail_parse.js +1 -1
  9. data/app/javascript/packs/owned_plugin_form.js +1 -1
  10. data/app/javascript/packs/settings.js +20 -9
  11. data/app/javascript/packs/transport_config.js +1 -1
  12. data/app/javascript/packs/transport_section.js +1 -1
  13. data/app/javascript/packs/treeview.js +2 -2
  14. data/app/models/plugin.rb +2 -2
  15. data/app/views/fluentd/settings/source_and_output.html.haml +12 -10
  16. data/app/views/layouts/application.html.erb +3 -0
  17. data/app/views/plugins/recommended.html.haml +3 -0
  18. data/app/views/plugins/updated.html.haml +5 -6
  19. data/config.ru +3 -1
  20. data/config/application.rb +1 -1
  21. data/config/application.yml +104 -31
  22. data/config/locales/translation_en.yml +1 -0
  23. data/config/locales/translation_ja.yml +1 -0
  24. data/gemfiles/ruby2.2.gemfile +2 -1
  25. data/lib/fluentd-ui/version.rb +1 -1
  26. data/test/application_system_test_case.rb +8 -0
  27. data/test/controllers/application_controller_test.rb +42 -0
  28. data/test/controllers/fluentd/agents_controller_test.rb +39 -0
  29. data/test/controllers/misc_controller_test.rb +70 -0
  30. data/test/controllers/polling_controller_test.rb +29 -0
  31. data/test/decorators/plugin_decorator_test.rb +26 -0
  32. data/{spec → test}/factories/fluentd.rb +0 -0
  33. data/{spec → test}/factories/plugins.rb +0 -0
  34. data/{spec → test}/factories/user.rb +0 -0
  35. data/{spec/support → test}/fixtures/error0.log +0 -0
  36. data/{spec/support → test}/fixtures/error2.log +0 -0
  37. data/{spec/support → test}/fixtures/error3.log +0 -0
  38. data/{spec/support → test}/fixtures/error4.log +0 -0
  39. data/{spec/support → test}/fixtures/multiline_example.log +0 -0
  40. data/test/integration/dashboard_test.rb +57 -0
  41. data/test/integration/fluentd/setting/histories_test.rb +139 -0
  42. data/test/integration/fluentd/setting/notes_test.rb +27 -0
  43. data/test/integration/fluentd/setting/running_backup_test.rb +65 -0
  44. data/test/integration/fluentd_ui_update_checking_test.rb +27 -0
  45. data/test/integration/sesstions_test.rb +56 -0
  46. data/test/integration/setting_test.rb +126 -0
  47. data/test/integration/users_test.rb +43 -0
  48. data/test/lib/filte_reverse_reader_test.rb +63 -0
  49. data/test/lib/fluentd_ui_test.rb +36 -0
  50. data/test/lib/regexp_preview/multi_line_test.rb +86 -0
  51. data/test/lib/regexp_preview/single_line_test.rb +87 -0
  52. data/test/models/fluent_gem_test.rb +76 -0
  53. data/test/models/fluentd/agent_test.rb +331 -0
  54. data/{spec/models/fluentd/setting/in_forward_spec.rb → test/models/fluentd/setting/in_forward_test.rb} +32 -44
  55. data/test/models/fluentd/setting/in_http_test.rb +30 -0
  56. data/test/models/fluentd/setting/in_monitor_agent_test.rb +30 -0
  57. data/test/models/fluentd/setting/in_syslog_test.rb +88 -0
  58. data/test/models/fluentd/setting/in_tail_test.rb +52 -0
  59. data/test/models/fluentd/setting/out_elasticsearch_test.rb +32 -0
  60. data/test/models/fluentd/setting/out_mongo_test.rb +61 -0
  61. data/test/models/fluentd/setting/out_s3_test.rb +112 -0
  62. data/test/models/fluentd/setting/out_stdout_test.rb +32 -0
  63. data/test/models/fluentd/setting/out_tdlog_test.rb +60 -0
  64. data/test/models/fluentd_log_test.rb +140 -0
  65. data/test/models/fluentd_test.rb +185 -0
  66. data/test/models/plugin_test.rb +144 -0
  67. data/test/models/user_test.rb +48 -0
  68. data/test/support/config_histories.rb +72 -0
  69. data/test/support/configurable_daemon_settings.rb +26 -0
  70. data/test/support/login_macro.rb +12 -0
  71. data/test/support/login_required.rb +8 -0
  72. data/test/support/stub_daemon.rb +14 -0
  73. data/test/system/fluentd/setting/in_forward_test.rb +13 -0
  74. data/test/system/fluentd/setting/in_http_test.rb +13 -0
  75. data/test/system/fluentd/setting/in_monitor_agent.rb +13 -0
  76. data/test/system/fluentd/setting/out_elasticsearch_test.rb +32 -0
  77. data/test/system/fluentd/setting/out_forward_test.rb +41 -0
  78. data/test/system/fluentd/setting/out_stdout_test.rb +15 -0
  79. data/test/system/fluentd/setting/out_tdlog_test.rb +15 -0
  80. data/test/system/source_and_output_test.rb +184 -0
  81. data/test/test_helper.rb +34 -0
  82. metadata +147 -161
  83. data/spec/controllers/application_controller_spec.rb +0 -84
  84. data/spec/controllers/fluentd/agents_controller_spec.rb +0 -61
  85. data/spec/controllers/misc_controller_spec.rb +0 -68
  86. data/spec/controllers/polling_controller_spec.rb +0 -39
  87. data/spec/controllers/sessions_controller_spec.rb +0 -5
  88. data/spec/decorators/plugin_decorator_spec.rb +0 -37
  89. data/spec/features/dashboard_spec.rb +0 -42
  90. data/spec/features/fluentd/setting/histories_spec.rb +0 -110
  91. data/spec/features/fluentd/setting/in_forward_spec.rb +0 -6
  92. data/spec/features/fluentd/setting/in_http_spec.rb +0 -6
  93. data/spec/features/fluentd/setting/in_monitor_agent_spec.rb +0 -6
  94. data/spec/features/fluentd/setting/notes_spec.rb +0 -27
  95. data/spec/features/fluentd/setting/out_forward_spec.rb +0 -38
  96. data/spec/features/fluentd/setting/out_stdout_spec.rb +0 -6
  97. data/spec/features/fluentd/setting/running_backup_spec.rb +0 -106
  98. data/spec/features/fluentd_status_spec.rb +0 -36
  99. data/spec/features/fluentd_ui_update_available_spec.rb +0 -33
  100. data/spec/features/out_elasticsearch_spec.rb +0 -28
  101. data/spec/features/out_forward_spec.rb +0 -36
  102. data/spec/features/out_tdlog_spec.rb +0 -26
  103. data/spec/features/sessions_spec.rb +0 -79
  104. data/spec/features/setting_spec.rb +0 -95
  105. data/spec/features/shared_examples/configurable_daemon_settings.rb +0 -17
  106. data/spec/features/shared_examples/login_required.rb +0 -4
  107. data/spec/features/source_and_output_spec.rb +0 -158
  108. data/spec/features/users_spec.rb +0 -53
  109. data/spec/grok_converter_spec.rb +0 -50
  110. data/spec/lib/file_reverse_reader_spec.rb +0 -93
  111. data/spec/lib/fluentd-ui_spec.rb +0 -35
  112. data/spec/lib/regexp_preview/multi_line_spec.rb +0 -111
  113. data/spec/lib/regexp_preview/single_line_spec.rb +0 -185
  114. data/spec/models/fluent_gem_spec.rb +0 -104
  115. data/spec/models/fluentd/agent/common_spec.rb +0 -82
  116. data/spec/models/fluentd/agent_spec.rb +0 -134
  117. data/spec/models/fluentd/setting/in_http_spec.rb +0 -31
  118. data/spec/models/fluentd/setting/in_monitor_agent_spec.rb +0 -31
  119. data/spec/models/fluentd/setting/in_syslog_spec.rb +0 -98
  120. data/spec/models/fluentd/setting/in_tail_spec.rb +0 -53
  121. data/spec/models/fluentd/setting/out_elasticsearch_spec.rb +0 -31
  122. data/spec/models/fluentd/setting/out_mongo_spec.rb +0 -62
  123. data/spec/models/fluentd/setting/out_s3_spec.rb +0 -128
  124. data/spec/models/fluentd/setting/out_stdout_spec.rb +0 -31
  125. data/spec/models/fluentd/setting/out_tdlog_spec.rb +0 -46
  126. data/spec/models/fluentd_log_spec.rb +0 -171
  127. data/spec/models/fluentd_spec.rb +0 -164
  128. data/spec/models/plugin_spec.rb +0 -191
  129. data/spec/models/user_spec.rb +0 -59
  130. data/spec/spec_helper.rb +0 -85
  131. data/spec/support/config_histories.rb +0 -57
  132. data/spec/support/fluentd_agent_common_behavior.rb +0 -181
  133. data/spec/support/fluentd_agent_restart_strategy.rb +0 -94
  134. data/spec/support/javascript_macro.rb +0 -21
  135. data/spec/support/login_macro.rb +0 -10
  136. data/spec/support/stub_daemon.rb +0 -12
@@ -0,0 +1,86 @@
1
+ require "test_helper"
2
+
3
+ module RegexpPreview
4
+ class MultilineTest < ActiveSupport::TestCase
5
+ test "simple usage" do
6
+ config = {
7
+ "format_firstline" => "/foo/",
8
+ "time_format" => "time_format",
9
+ }
10
+ config["format1"] = "/(?<foo>foo)\n/"
11
+ config["format2"] = "/(?<bar>bar)/"
12
+ 3.upto(Fluentd::Setting::InTail::MULTI_LINE_MAX_FORMAT_COUNT) do |i|
13
+ config["format#{i}"] = "//"
14
+ end
15
+ preview = RegexpPreview::MultiLine.new(fixture_path("error0.log"), "multiline", config)
16
+ matches = [
17
+ {
18
+ whole: "foo\nbar\nbaz\n1\n2\n3\n4\n5\n6\n10\n11\n12",
19
+ matches: [
20
+ { key: "foo", matched: "foo", pos: [0, 3] },
21
+ { key: "bar", matched: "bar", pos: [4, 7] }
22
+ ]
23
+ }
24
+ ]
25
+ assert_equal(matches, preview.matches[:matches])
26
+ end
27
+
28
+ test "detect only continuous patterns" do
29
+ config = {
30
+ "format_firstline" => "/foo/",
31
+ "time_format" => "time_format",
32
+ }
33
+ config["format1"] = "/(?<foo>foo)\n/"
34
+ config["format2"] = "/(?<bar>baz)/"
35
+ 3.upto(Fluentd::Setting::InTail::MULTI_LINE_MAX_FORMAT_COUNT) do |i|
36
+ config["format#{i}"] = "//"
37
+ end
38
+ preview = RegexpPreview::MultiLine.new(fixture_path("error0.log"), "multiline", config)
39
+ assert_equal([], preview.matches[:matches])
40
+ end
41
+
42
+ # http://docs.fluentd.org/articles/in_tail
43
+ test "example on document" do
44
+ config = {
45
+ "format_firstline" => "/\\d{4}-\\d{1,2}-\\d{1,2}/",
46
+ "format1" => "/^(?<time>\\d{4}-\\d{1,2}-\\d{1,2} \\d{1,2}:\\d{1,2}:\\d{1,2}) \\[(?<thread>.*)\\] (?<level>[^\\s]+)(?<message>.*)/",
47
+ "time_format" => "%Y-%m-%d %H:%M:%S",
48
+ "keep_time_key" => true
49
+ }
50
+ 2.upto(Fluentd::Setting::InTail::MULTI_LINE_MAX_FORMAT_COUNT) do |i|
51
+ config["format#{i}"] = "//"
52
+ end
53
+ preview = RegexpPreview::MultiLine.new(fixture_path("multiline_example.log"), "multiline", config)
54
+ matches = [
55
+ {
56
+ whole: "2013-3-03 14:27:33 [main] INFO Main - Start\n",
57
+ matches: [
58
+ { key: "time", matched: "2013-3-03 14:27:33", pos: [0, 18] },
59
+ { key: "thread", matched: "main", pos: [20, 24] },
60
+ { key: "level", matched: "INFO", pos: [26, 30] },
61
+ { key: "message", matched: " Main - Start\n", pos: [30, 45] }
62
+ ]
63
+ },
64
+ {
65
+ whole: "2013-3-03 14:27:33 [main] ERROR Main - Exception\njavax.management.RuntimeErrorException: null\n at Main.main(Main.java:16) ~[bin/:na]\n",
66
+ matches: [
67
+ { key: "time", matched: "2013-3-03 14:27:33", pos: [0, 18] },
68
+ { key: "thread", matched: "main", pos: [20, 24] },
69
+ { key: "level", matched: "ERROR", pos: [26, 31] },
70
+ { key: "message", matched: " Main - Exception\njavax.management.RuntimeErrorException: null\n at Main.main(Main.java:16) ~[bin/:na]\n", pos: [31, 136] },
71
+ ]
72
+ },
73
+ {
74
+ whole: "2013-3-03 14:27:33 [main] INFO Main - End",
75
+ matches: [
76
+ { key: "time", matched: "2013-3-03 14:27:33", pos: [0, 18] },
77
+ { key: "thread", matched: "main", pos: [20, 24] },
78
+ { key: "level", matched: "INFO", pos: [26, 30] },
79
+ { key: "message", matched: " Main - End", pos: [30, 42] },
80
+ ]
81
+ }
82
+ ]
83
+ assert_equal(matches, preview.matches[:matches])
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,87 @@
1
+ require "test_helper"
2
+ require "fluent/plugin/parser_apache"
3
+ require "fluent/plugin/parser_nginx"
4
+
5
+ module RegexpPreview
6
+ class SingleLineTest < ActiveSupport::TestCase
7
+ data("regexp" => ["regexp", Fluent::Plugin::RegexpParser, { "expression" => "(?<catefory>\[.+\])", "time_format" => "%Y/%m/%d" }],
8
+ "ltsv" => ["ltsv", Fluent::Plugin::LabeledTSVParser, {}],
9
+ "json" => ["json", Fluent::Plugin::JSONParser, {}],
10
+ "csv" => ["csv", Fluent::Plugin::CSVParser, { "keys" => "column1,column2" }],
11
+ "tsv" => ["tsv", Fluent::Plugin::TSVParser, { "keys" => "column1,column2" }],
12
+ "syslog" => ["syslog", Fluent::Plugin::SyslogParser, {}],
13
+ "apache" => ["apache", Fluent::Plugin::ApacheParser, {}],
14
+ "nginx" => ["nginx", Fluent::Plugin::NginxParser, {}])
15
+ test "create parser plugin instance from selected plugin name" do |(name, klass, config)|
16
+ preview = RegexpPreview::SingleLine.new("log_file.log", name, config)
17
+ assert_instance_of(klass, preview.plugin)
18
+ end
19
+
20
+ sub_test_case "#matches" do
21
+ test "regexp" do
22
+ config = {
23
+ "expression" => "(?<regexp>bar)", # bar from error0.log
24
+ "time_format" => "time_format",
25
+ }
26
+ preview = RegexpPreview::SingleLine.new(fixture_path("error0.log"), "regexp", config)
27
+ matches = [
28
+ {
29
+ whole: "bar",
30
+ matches: [
31
+ { key: "regexp", matched: "bar", pos: [0, 3] }
32
+ ]
33
+ }
34
+ ]
35
+ assert_equal(config, preview.matches[:pluginConfig])
36
+ assert_equal(matches,preview.matches[:matches])
37
+ end
38
+
39
+ test "csv" do
40
+ config = { "keys" => "column1,column2" }
41
+ preview = RegexpPreview::SingleLine.new(fixture_path("error0.log"), "csv", config)
42
+ assert do
43
+ preview.matches[:matches].empty?
44
+ end
45
+ end
46
+
47
+ test "syslog" do
48
+ config = {
49
+ "time_format" => "%Y-%m-%d %H:%M:%S %z",
50
+ "keep_time_key" => true
51
+ }
52
+ preview = RegexpPreview::SingleLine.new(fixture_path("error4.log"), "syslog", config)
53
+ matches = [
54
+ {
55
+ whole: "2014-05-27 10:54:37 +0900 [info]: listening fluent socket on 0.0.0.0:24224",
56
+ matches: [
57
+ { key: "time", matched: "2014-05-27 10:54:37 +0900", pos: [0, 25] },
58
+ { key: "host", matched: "[info]:", pos: [26, 33] },
59
+ { key: "ident", matched: "listening", pos: [34, 43] },
60
+ { key: "message", matched: "24224", pos: [69, 74] }
61
+ ]
62
+ }
63
+ ]
64
+ assert_equal(matches, preview.matches[:matches])
65
+ end
66
+
67
+ test "syslog when keep_time_key is false" do
68
+ config = {
69
+ "time_format" => "%Y-%m-%d %H:%M:%S %z",
70
+ "keep_time_key" => false
71
+ }
72
+ preview = RegexpPreview::SingleLine.new(fixture_path("error4.log"), "syslog", config)
73
+ matches = [
74
+ {
75
+ whole: "2014-05-27 10:54:37 +0900 [info]: listening fluent socket on 0.0.0.0:24224",
76
+ matches: [
77
+ { key: "host", matched: "[info]:", pos: [26, 33] },
78
+ { key: "ident", matched: "listening", pos: [34, 43] },
79
+ { key: "message", matched: "24224", pos: [69, 74] }
80
+ ]
81
+ }
82
+ ]
83
+ assert_equal(matches, preview.matches[:matches])
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,76 @@
1
+ require "test_helper"
2
+
3
+ class FluentGemTest < ActiveSupport::TestCase
4
+
5
+ data("no arguments" => [],
6
+ "1 argument" => ["plugin-foo"],
7
+ "2 arguments" => ["plugin-foo", "--no-document"])
8
+ test "install" do |args|
9
+ if args.empty?
10
+ mock(FluentGem).run("install")
11
+ FluentGem.install
12
+ else
13
+ mock(FluentGem).run("install", *args)
14
+ FluentGem.install(*args)
15
+ end
16
+ end
17
+
18
+ data("no arguments" => [],
19
+ "1 argument" => ["plugin-foo"],
20
+ "2 arguments" => ["plugin-foo", "--no-document"])
21
+ test "uninstall" do |args|
22
+ if args.empty?
23
+ mock(FluentGem).run("uninstall")
24
+ FluentGem.uninstall
25
+ else
26
+ mock(FluentGem).run("uninstall", *args)
27
+ FluentGem.uninstall(*args)
28
+ end
29
+ end
30
+
31
+ data("no list" => "",
32
+ "some lines" => <<-GEM_LIST.strip_heredoc)
33
+ dummy (3.3.3)
34
+ fluent-plugin-foo (0.1.2)
35
+ more_dummy (0.0.1)
36
+ GEM_LIST
37
+ test "list" do |gem_list|
38
+ stub(FluentGem).gem { "gem" }
39
+ stub(FluentGem).__double_definition_create__.call(:`, "gem list 2>&1") { gem_list }
40
+ assert_equal(gem_list.lines.to_a, FluentGem.list)
41
+ end
42
+
43
+ sub_test_case("run") do
44
+ test "success" do
45
+ stub(FluentGem).gem { "gem" }
46
+ args = ["install", "foobar"]
47
+ stub(FluentGem).system("gem", *args) { true }
48
+ assert_true(FluentGem.run(*args))
49
+ end
50
+
51
+ test "failure" do
52
+ stub(FluentGem).gem { "gem" }
53
+ args = ["install", "foobar"]
54
+ stub(FluentGem).system("gem", *args) { false }
55
+ assert_raise(FluentGem::GemError) do
56
+ FluentGem.run(*args)
57
+ end
58
+ end
59
+ end
60
+
61
+ sub_test_case "gem" do
62
+ test "any instance not setup yet" do
63
+ assert_equal("fluent-gem", FluentGem.gem)
64
+ end
65
+
66
+ test "fluentd setup" do
67
+ stub(Fluentd).instance { Fluentd.new(id: nil, variant: "fluentd_gem", log_file: "dummy.log", pid_file: "dummy.pid", config_file: "dummy.conf") }
68
+ assert_equal("fluent-gem", FluentGem.gem)
69
+ end
70
+
71
+ test "td-agent 3 setup" do
72
+ stub(Fluentd).instance { Fluentd.new(id: nil, variant: "td_agent", log_file: "dummy.log", pid_file: "dummy.pid", config_file: "dummy.conf") }
73
+ assert_equal(FluentGem.detect_td_agent_gem, FluentGem.gem)
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,331 @@
1
+ require "test_helper"
2
+
3
+ class Fluentd
4
+ class AgentTest < ActiveSupport::TestCase
5
+ module CommonBehavior
6
+ extend ActiveSupport::Concern
7
+ included do
8
+ sub_test_case "#extra_options" do
9
+ test "blank" do
10
+ @agent = @klass.new({})
11
+ assert_equal({}, @agent.extra_options)
12
+ extra_options = {
13
+ config_file: @agent.config_file,
14
+ log_file: @agent.log_file,
15
+ pid_file: @agent.pid_file
16
+ }
17
+ assert_equal(extra_options, @klass.default_options)
18
+ end
19
+
20
+ test "given" do
21
+ options = {
22
+ config_file: "pid",
23
+ log_file: "log",
24
+ pid_file: "config"
25
+ }
26
+ @agent = @klass.new(options)
27
+ extra_options = {
28
+ config_file: @agent.config_file,
29
+ log_file: @agent.log_file,
30
+ pid_file: @agent.pid_file
31
+ }
32
+ assert_equal(extra_options, options)
33
+ end
34
+ end
35
+
36
+ sub_test_case "#errors_since" do
37
+ setup do
38
+ @logged_time = Time.parse('2014-05-27')
39
+ @now = Time.parse("2014-05-29")
40
+ Timecop.freeze(@now)
41
+ end
42
+
43
+ teardown do
44
+ Timecop.return
45
+ end
46
+
47
+ test "have no errors" do
48
+ stub(@agent).log_file { fixture_path("error0.log") }
49
+ assert do
50
+ @agent.log.errors_since(100.days.ago).empty?
51
+ end
52
+ end
53
+
54
+ sub_test_case "have errors" do
55
+ test "unreachable since 0 days ago" do
56
+ stub(@agent).log_file { fixture_path("error2.log") }
57
+ assert_equal([], @agent.log.errors_since(0.days.ago))
58
+ end
59
+
60
+ test "reachable since 100 days ago" do
61
+ stub(@agent).log_file { fixture_path("error2.log") }
62
+ logs = @agent.log.errors_since(100.days.ago)
63
+ assert do
64
+ logs[0][:subject].include?("Address already in use - bind(2)")
65
+ end
66
+ one = Time.parse(logs[0][:subject])
67
+ two = Time.parse(logs[1][:subject])
68
+ assert do
69
+ one >= two
70
+ end
71
+ end
72
+ end
73
+ end
74
+
75
+ sub_test_case "#recent_errors" do
76
+ test "have 0 error log" do
77
+ stub(@agent).log_file { fixture_path("error0.log") }
78
+ assert do
79
+ @agent.log.recent_errors(2).empty?
80
+ end
81
+ end
82
+
83
+ sub_test_case "have 2 error log" do
84
+ setup do
85
+ stub(@agent).log_file { fixture_path("error2.log") }
86
+ end
87
+
88
+ data("limit 1" => 1,
89
+ "limit 2" => 2)
90
+ test "limit" do |limit|
91
+ assert do
92
+ limit == @agent.log.recent_errors(limit).size
93
+ end
94
+ end
95
+
96
+ test "contains stack trace" do
97
+ logs = @agent.log.recent_errors(2)
98
+ assert do
99
+ logs[0][:subject].include?("Address already in use - bind(2)")
100
+ end
101
+ end
102
+
103
+ test "newer(bottom) is first" do
104
+ logs = @agent.log.recent_errors(2)
105
+ one = Time.parse(logs[0][:subject])
106
+ two = Time.parse(logs[1][:subject])
107
+ assert do
108
+ one >= two
109
+ end
110
+ end
111
+ end
112
+
113
+ sub_test_case "have 3 errors log including sequential 2 error log" do
114
+ setup do
115
+ stub(@agent).log_file { fixture_path("error3.log") }
116
+ end
117
+
118
+ test "count 3 errors" do
119
+ logs = @agent.log.recent_errors(3)
120
+ assert_equal(logs[0][:subject].slice(/::EADDRINUSE: (\d) Address already in use/, 1), "3")
121
+ assert_equal(logs[0][:notes].size, 1)
122
+ assert_equal(logs[1][:subject].slice(/::EADDRINUSE: (\d) Address already in use/, 1), "2")
123
+ assert_equal(logs[1][:notes].size, 2)
124
+ assert_equal(logs[2][:subject].slice(/::EADDRINUSE: (\d) Address already in use/, 1), "1")
125
+ assert_equal(logs[2][:notes].size, 0)
126
+ end
127
+ end
128
+ end
129
+
130
+ sub_test_case "#dryrun" do
131
+ setup do
132
+ pend("/usr/sbin/td-agent does not exist") unless File.exist?("/usr/sbin/td-agent")
133
+ @root = FluentdUI.data_dir + "/tmp/agent-test/"
134
+ @dummy_log_file = @root + "dummy.log"
135
+ @dummy_pid_file = @root + "dummy.pid"
136
+
137
+ FileUtils.mkdir_p(@root)
138
+ stub(@agent).log_file { @dummy_log_file }
139
+ stub(@agent).pid_file { @dummy_pid_file }
140
+ end
141
+
142
+ sub_test_case "valid/invalid" do
143
+ setup do
144
+ @config_path = Rails.root.join("tmp", "fluent-test.conf").to_s
145
+ end
146
+
147
+ teardown do
148
+ File.unlink(@config_path) if @config_path && File.exist?(@config_path)
149
+ end
150
+
151
+ test "valid config" do
152
+ config = <<-CONF.strip_heredoc
153
+ <source>
154
+ @type forward
155
+ </source>
156
+ CONF
157
+ File.write(@config_path, config)
158
+ assert_nothing_raised do
159
+ @agent.dryrun!(@config_path)
160
+ end
161
+ assert_true(@agent.dryrun(@config_path))
162
+ end
163
+
164
+ test "invalid config" do
165
+ config = <<-CONF.strip_heredoc
166
+ <source>
167
+ @type forward
168
+ CONF
169
+ File.write(@config_path, config)
170
+ assert_raise(Fluentd::Agent::ConfigError) do
171
+ @agent.dryrun!(@config_path)
172
+ end
173
+ assert_false(@agent.dryrun(@config_path))
174
+ end
175
+ end
176
+ end
177
+ end
178
+ end
179
+
180
+ module RestartStrategy
181
+ extend ActiveSupport::Concern
182
+
183
+ included do
184
+ setup do
185
+ options = {
186
+ config_file: Rails.root.join("tmp", "fluentd-test", "fluentd.conf").to_s
187
+ }
188
+ @klass = Fluentd::Agent::FluentdGem
189
+ @agent = @klass.new(options)
190
+ end
191
+
192
+ data("succeeded to start" => true,
193
+ "failed to stard" => false)
194
+ test "not running" do |start|
195
+ stub(@agent).running? { false }
196
+ stub(@agent).start { start }
197
+ assert_equal(start, @agent.restart)
198
+ end
199
+
200
+ sub_test_case "running" do
201
+ data("stop: success, start: success" => [true, true, true],
202
+ "stop: success, start: failure" => [true, false, false],
203
+ "stop: failure, start: success" => [false, true, false],
204
+ "stop: failure, start: failure" => [false, false, false])
205
+ test "#validate_fluentd_options success" do |(stop_result, start_result, restarted)|
206
+ stub(@agent).validate_fluentd_options { true }
207
+ stub(@agent).running? { true }
208
+ stub(@agent).start { stop_result }
209
+ stub(@agent).stop { start_result }
210
+ assert_equal(restarted, @agent.restart)
211
+ end
212
+
213
+ data("stop: success, start: success" => [true, true, false],
214
+ "stop: success, start: failure" => [true, false, false],
215
+ "stop: failure, start: success" => [false, true, false],
216
+ "stop: failure, start: failure" => [false, false, false])
217
+ test "#validate_fluentd_options failure" do |(stop_result, start_result, restarted)|
218
+ stub(@agent).validate_fluentd_options { false }
219
+ stub(@agent).running? { true }
220
+ stub(@agent).start { stop_result }
221
+ stub(@agent).stop { start_result }
222
+ assert_equal(restarted, @agent.restart)
223
+ end
224
+ end
225
+ end
226
+ end
227
+
228
+ sub_test_case "FluentdGem" do
229
+ setup do
230
+ options = {
231
+ config_file: Rails.root.join("tmp", "fluentd-test", "fluentd.conf").to_s
232
+ }
233
+ @klass = Fluentd::Agent::FluentdGem
234
+ @agent = @klass.new(options)
235
+ end
236
+
237
+ include CommonBehavior
238
+
239
+ test "#options_to_argv" do
240
+ expected_argv = " -c #{@agent.config_file} -d #{@agent.pid_file} -o #{@agent.log_file}"
241
+ assert_equal(expected_argv, @agent.__send__(:options_to_argv))
242
+ end
243
+
244
+ sub_test_case "#start" do
245
+ setup do
246
+ # ensure valid config
247
+ @agent.config_write("")
248
+ end
249
+
250
+ teardown do
251
+ FileUtils.rm_rf(@agent.running_config_backup_dir)
252
+ end
253
+
254
+ test "running" do
255
+ stub(@agent).running? { true }
256
+ assert_true(@agent.start)
257
+ end
258
+
259
+ test "succeeded to actual_start" do
260
+ stub(@agent).running? { false }
261
+ stub(@agent).actual_start { true }
262
+ assert_true(@agent.start)
263
+ backup_file = @agent.running_config_backup_file
264
+ assert do
265
+ File.exist?(backup_file)
266
+ end
267
+ assert_equal(File.read(@agent.config_file), File.read(backup_file))
268
+ end
269
+
270
+ test "failed to actual_start" do
271
+ stub(@agent).running? { false }
272
+ stub(@agent).actual_start { false }
273
+ assert_nil(@agent.start)
274
+ end
275
+ end
276
+
277
+ sub_test_case "#stop" do
278
+ data("succeeded to actual_stop" => true,
279
+ "failed to actual_stop" => false)
280
+ test "running" do |stop_result|
281
+ stub(@agent).running? { true }
282
+ stub(@agent).actual_stop { stop_result }
283
+ assert_equal(stop_result, @agent.stop)
284
+ end
285
+
286
+ test "not running" do
287
+ stub(@agent).running? { false }
288
+ assert do
289
+ @agent.stop
290
+ end
291
+ end
292
+ end
293
+
294
+ sub_test_case "#restart" do
295
+ include RestartStrategy
296
+ end
297
+ end
298
+
299
+ sub_test_case "TdAgent" do
300
+ setup do
301
+ options = {
302
+ config_file: Rails.root.join("tmp", "fluentd-test", "fluentd.conf").to_s
303
+ }
304
+ @klass = Fluentd::Agent::TdAgent
305
+ @agent = @klass.new(options)
306
+ end
307
+
308
+ include CommonBehavior
309
+
310
+ sub_test_case "#backup_running_config" do
311
+ setup do
312
+ stub(@agent).detached_command { true }
313
+ stub(@agent).pid_from_launchctl { true }
314
+ @agent.config_write("") # ensure valid config
315
+ end
316
+
317
+ teardown do
318
+ FileUtils.rm_rf(@agent.running_config_backup_dir)
319
+ end
320
+
321
+
322
+ test "backup running conf" do
323
+ @agent.start
324
+ backup_file = @agent.running_config_backup_file
325
+ assert_true(File.exist?(backup_file))
326
+ assert_equal(File.read(@agent.config_file), File.read(backup_file))
327
+ end
328
+ end
329
+ end
330
+ end
331
+ end