# Copyright 2016 Google Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require_relative '../helper' require 'fluent/plugin/exception_detector' class ExceptionDetectorTest < Test::Unit::TestCase JAVA_EXC_PART1 = <:3:9) at :6:4 at a_function_name at Object.InjectedScript._evaluateOn (http:///file.js?foo=bar:875:140) at Object.InjectedScript.evaluate () END V8_JS_EXC = <__call('raise', Array) #3 /base/data/home/apps/s~crash-example-php/1.388306779641080894/index.php(36): ErrorEntry->raise() #4 {main} thrown in /base/data/home/apps/s~crash-example-php/1.388306779641080894/errors.php on line 60 END GO_EXC = <:0 at File3.Consolidator_Class.Function5 (System.Collections.Generic.Dictionary`2 names, System.Text.StringBuilder param_4) [0x00007] in /usr/local/google/home/Csharp/another file.csharp:9 at File3.Consolidator_Class.Function4 (System.Text.StringBuilder param_4, System.Double[,,] array) [0x00013] in /usr/local/google/home/Csharp/another file.csharp:23 at File3.Consolidator_Class.Function3 (Int32 param_3) [0x0000f] in /usr/local/google/home/Csharp/another file.csharp:27 at File3.Consolidator_Class.Function3 (System.Text.StringBuilder param_3) [0x00007] in /usr/local/google/home/Csharp/another file.csharp:32 at File2.Processor.Function2 (System.Int32& param_2, System.Collections.Generic.Stack`1& numbers) [0x00003] in /usr/local/google/home/Csharp/File2.csharp:19 at File2.Processor.Random2 () [0x00037] in /usr/local/google/home/Csharp/File2.csharp:28 at File2.Processor.Function1 (Int32 param_1, System.Collections.Generic.Dictionary`2 map) [0x00007] in /usr/local/google/home/Csharp/File2.csharp:34 at Main.Welcome+
c__AnonStorey0.<>m__0 () [0x00006] in /usr/local/google/home/Csharp/hello.csharp:48 at System.Threading.Thread.StartInternal () [0x00000] in :0 END RUBY_EXC = <): app/controllers/books_controller.rb:69:in `recursivewordload' app/controllers/books_controller.rb:75:in `loadword' app/controllers/books_controller.rb:79:in `loadline' app/controllers/books_controller.rb:83:in `loadparagraph' app/controllers/books_controller.rb:87:in `loadpage' app/controllers/books_controller.rb:91:in `onload' app/controllers/books_controller.rb:95:in `loadrecursive' app/controllers/books_controller.rb:99:in `requestload' app/controllers/books_controller.rb:118:in `generror' config/error_reporting_logger.rb:62:in `tagged' END # The whitespace on the second line is significant. # rubocop:disable TrailingWhitespace RAILS_EXC = < (file:///path/to/code/dartFile.dart:15:20) #1 printError (file:///path/to/code/dartFile.dart:37:13) #2 main (file:///path/to/code/dartFile.dart:15:3) #3 _startIsolate. (dart:isolate-patch/isolate_patch.dart:265) #4 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:151) END DART_EXC = < (file:///path/to/code/dartFile.dart:17:20) #1 printError (file:///path/to/code/dartFile.dart:37:13) #2 main (file:///path/to/code/dartFile.dart:17:3) #3 _startIsolate. (dart:isolate-patch/isolate_patch.dart:265) #4 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:151) END DART_ASYNC_ERR = < #2 _startIsolate. (dart:isolate-patch/isolate_patch.dart:265) #3 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:151) END DART_DIVIDE_BY_ZERO_ERR = < (file:///path/to/code/dartFile.dart:27:20) #1 printError (file:///path/to/code/dartFile.dart:42:13) #2 main (file:///path/to/code/dartFile.dart:27:3) #3 _startIsolate. (dart:isolate-patch/isolate_patch.dart:265) #4 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:151) END DART_ARGUMENT_ERR = < (file:///path/to/code/dartFile.dart:23:20) #1 printError (file:///path/to/code/dartFile.dart:42:13) #2 main (file:///path/to/code/dartFile.dart:23:3) #3 _startIsolate. (dart:isolate-patch/isolate_patch.dart:265) #4 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:151) END DART_RANGE_ERR = < (file:///path/to/code/dartFile.dart:31:23) #2 printError (file:///path/to/code/dartFile.dart:42:13) #3 main (file:///path/to/code/dartFile.dart:29:3) #4 _startIsolate. (dart:isolate-patch/isolate_patch.dart:265) #5 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:151) END DART_ASSERTION_ERR = < (file:///path/to/code/dartFile.dart:9:20) #1 printError (file:///path/to/code/dartFile.dart:36:13) #2 main (file:///path/to/code/dartFile.dart:9:3) #3 _startIsolate. (dart:isolate-patch/isolate_patch.dart:265) #4 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:151) END DART_ABSTRACT_CLASS_ERR = < (file:///path/to/code/dartFile.dart:12:20) #1 printError (file:///path/to/code/dartFile.dart:36:13) #2 main (file:///path/to/code/dartFile.dart:12:3) #3 _startIsolate. (dart:isolate-patch/isolate_patch.dart:265) #4 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:151) END DART_READ_STATIC_ERR = < (file:///path/to/code/dartFile.dart:28:20) #1 printError (file:///path/to/code/dartFile.dart:43:13) #2 main (file:///path/to/code/dartFile.dart:28:3) #3 _startIsolate. (dart:isolate-patch/isolate_patch.dart:265) #4 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:151) END DART_UNIMPLEMENTED_ERROR = < (file:///path/to/code/dartFile.dart:38:20) #1 printError (file:///path/to/code/dartFile.dart:61:13) #2 main (file:///path/to/code/dartFile.dart:38:3) #3 _startIsolate. (dart:isolate-patch/isolate_patch.dart:265) #4 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:151) END DART_UNSUPPORTED_ERR = < (file:///path/to/code/dartFile.dart:36:20) #1 printError (file:///path/to/code/dartFile.dart:61:13) #2 main (file:///path/to/code/dartFile.dart:36:3) #3 _startIsolate. (dart:isolate-patch/isolate_patch.dart:265) #4 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:151) END DART_CONCURRENT_MODIFICATION_ERR = < (file:///path/to/code/dartFile.dart:35:20) #1 printError (file:///path/to/code/dartFile.dart:61:13) #2 main (file:///path/to/code/dartFile.dart:35:3) #3 _startIsolate. (dart:isolate-patch/isolate_patch.dart:265) #4 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:151) END DART_OOM_ERR = < (file:///path/to/code/dartFile.dart:34:20) #1 printError (file:///path/to/code/dartFile.dart:61:13) #2 main (file:///path/to/code/dartFile.dart:34:3) #3 _startIsolate. (dart:isolate-patch/isolate_patch.dart:265) #4 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:151) END DART_STACK_OVERFLOW_ERR = < (file:///path/to/code/dartFile.dart:33:20) #1 printError (file:///path/to/code/dartFile.dart:61:13) #2 main (file:///path/to/code/dartFile.dart:33:3) #3 _startIsolate. (dart:isolate-patch/isolate_patch.dart:265) #4 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:151) END DART_FALLTHROUGH_ERR = < (file:///path/to/code/dartFile.dart:39:20) #1 printError (file:///path/to/code/dartFile.dart:51:13) #2 main (file:///path/to/code/dartFile.dart:39:3) #3 _startIsolate. (dart:isolate-patch/isolate_patch.dart:265) #4 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:151) END DART_TYPE_ERR = < (file:///path/to/code/dartFile.dart:7:24) #2 printError (file:///path/to/code/dartFile.dart:36:13) #3 main (file:///path/to/code/dartFile.dart:7:3) #4 _startIsolate. (dart:isolate-patch/isolate_patch.dart:265) #5 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:151) END DART_FORMAT_ERR = < (file:///path/to/code/dartFile.dart:25:20) #1 printError (file:///path/to/code/dartFile.dart:42:13) #2 main (file:///path/to/code/dartFile.dart:25:3) #3 _startIsolate. (dart:isolate-patch/isolate_patch.dart:265) #4 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:151) END DART_FORMAT_WITH_CODE_ERR = < (file:///path/to/code/dartFile.dart:24:20) #1 printError (file:///path/to/code/dartFile.dart:42:13) #2 main (file:///path/to/code/dartFile.dart:24:3) #3 _startIsolate. (dart:isolate-patch/isolate_patch.dart:265) #4 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:151) END DART_NO_METHOD_ERR = < (file:///path/to/code/dartFile.dart:8:39) #2 printError (file:///path/to/code/dartFile.dart:36:13) #3 main (file:///path/to/code/dartFile.dart:8:3) #4 _startIsolate. (dart:isolate-patch/isolate_patch.dart:265) #5 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:151) END DART_NO_METHOD_GLOBAL_ERR = < (file:///path/to/code/dartFile.dart:10:20) #2 printError (file:///path/to/code/dartFile.dart:36:13) #3 main (file:///path/to/code/dartFile.dart:10:3) #4 _startIsolate. (dart:isolate-patch/isolate_patch.dart:265) #5 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:151) END ARBITRARY_TEXT = < line) end buffer.flush end end def expected_json(message_field, messages) messages.collect { |m| { message_field => [m].flatten.join } } end Struct.new('TestJsonScenario', :desc, :configured_field, :actual_field, :input, :output) def json_scenario(desc, configured_field, actual_field, input, output) Struct::TestJsonScenario.new(desc, configured_field, actual_field, input, output) end def test_json_messages [ json_scenario('User-defined message field', 'mydata', 'mydata', [PYTHON_EXC, ARBITRARY_TEXT, GO_EXC], [PYTHON_EXC] + ARBITRARY_TEXT.lines + [GO_EXC]), json_scenario('Default message field "message"', '', 'message', [PYTHON_EXC, ARBITRARY_TEXT, GO_EXC], [PYTHON_EXC] + ARBITRARY_TEXT.lines + [GO_EXC]), json_scenario('Default message field "log"', '', 'log', [PYTHON_EXC, ARBITRARY_TEXT, GO_EXC], [PYTHON_EXC] + ARBITRARY_TEXT.lines + [GO_EXC]), json_scenario('Wrongly defined message field', 'doesnotexist', 'mydata', [PYTHON_EXC, ARBITRARY_TEXT, GO_EXC], PYTHON_EXC.lines + ARBITRARY_TEXT.lines + GO_EXC.lines), json_scenario('Undefined message field', '', 'mydata', [PYTHON_EXC, ARBITRARY_TEXT, GO_EXC], PYTHON_EXC.lines + ARBITRARY_TEXT.lines + GO_EXC.lines) ].each do |s| out = [] buffer = Fluent::TraceAccumulator.new(s.configured_field, [:all]) { |_, m| out << m } feed_json(buffer, s.actual_field, s.input) assert_equal(expected_json(s.actual_field, s.output), out, s.desc) end end def test_max_lines_limit # Limit is equal to the first part of the exception and forces it to be # flushed before the rest of the exception is processed. max_lines = JAVA_EXC_PART1.lines.length out = [] buffer = Fluent::TraceAccumulator.new(nil, [:all], max_lines: max_lines) do |_, m| out << m end feed_lines(buffer, JAVA_EXC) assert_equal([JAVA_EXC_PART1] + JAVA_EXC_PART2.lines, out) end def test_high_max_bytes_limit # Limit is just too small to add one more line to the buffered first part of # the exception. max_bytes = JAVA_EXC_PART1.length + JAVA_EXC_PART2.lines[0].length - 1 out = [] buffer = Fluent::TraceAccumulator.new(nil, [:all], max_bytes: max_bytes) do |_, m| out << m end feed_lines(buffer, JAVA_EXC) # Check that the trace is flushed after the first part. assert_equal([JAVA_EXC_PART1] + JAVA_EXC_PART2.lines, out) end def test_low_max_bytes_limit # Limit is exceeded by the character that follows the buffered first part of # the exception. max_bytes = JAVA_EXC_PART1.length out = [] buffer = Fluent::TraceAccumulator.new(nil, [:all], max_bytes: max_bytes) do |_, m| out << m end feed_lines(buffer, JAVA_EXC) # Check that the trace is flushed after the first part. assert_equal([JAVA_EXC_PART1] + JAVA_EXC_PART2.lines, out) end def test_join_separator # Custom join separator is used to join accumulated output join_separator = ';' out = [] buffer = Fluent::TraceAccumulator.new(nil, [:all], join_separator: join_separator) do |_, m| out << m end feed_lines(buffer, JAVA_EXC) assert_equal(JAVA_EXC.lines.length - 1, out[0].count(join_separator)) end end