newrelic_plugin 1.0.3 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/.gitignore +1 -0
  2. data/CHANGELOG.md +44 -1
  3. data/README.md +11 -5
  4. data/lib/newrelic_platform_binding.rb +11 -0
  5. data/lib/newrelic_platform_binding/component.rb +27 -0
  6. data/lib/newrelic_platform_binding/config.rb +39 -0
  7. data/lib/newrelic_platform_binding/connection.rb +86 -0
  8. data/lib/newrelic_platform_binding/context.rb +49 -0
  9. data/lib/newrelic_platform_binding/logger.rb +40 -0
  10. data/lib/newrelic_platform_binding/metric.rb +49 -0
  11. data/lib/newrelic_platform_binding/request.rb +111 -0
  12. data/lib/newrelic_plugin.rb +1 -4
  13. data/lib/newrelic_plugin/agent.rb +14 -21
  14. data/lib/newrelic_plugin/config.rb +2 -1
  15. data/lib/newrelic_plugin/processors/rate_processor.rb +3 -3
  16. data/lib/newrelic_plugin/run.rb +97 -54
  17. data/lib/newrelic_plugin/setup.rb +10 -19
  18. data/lib/newrelic_plugin/version.rb +1 -1
  19. data/newrelic_plugin.gemspec +4 -4
  20. data/test/newrelic_platform_binding/component_test.rb +16 -0
  21. data/test/newrelic_platform_binding/config_test.rb +89 -0
  22. data/test/newrelic_platform_binding/connection_test.rb +67 -0
  23. data/test/newrelic_platform_binding/context_test.rb +35 -0
  24. data/test/newrelic_platform_binding/logger_test.rb +33 -0
  25. data/test/newrelic_platform_binding/metric_test.rb +97 -0
  26. data/test/newrelic_platform_binding/request_test.rb +127 -0
  27. data/test/newrelic_plugin/agent_test.rb +127 -0
  28. data/test/newrelic_plugin/run_test.rb +77 -0
  29. data/test/newrelic_plugin/setup_test.rb +17 -0
  30. data/test/test_helper.rb +11 -4
  31. metadata +59 -17
  32. data/lib/newrelic_plugin/data_collector.rb +0 -67
  33. data/lib/newrelic_plugin/logger.rb +0 -19
  34. data/lib/newrelic_plugin/new_relic_connection.rb +0 -67
  35. data/lib/newrelic_plugin/new_relic_message.rb +0 -173
  36. data/test/agent_test.rb +0 -153
  37. data/test/logger_test.rb +0 -21
  38. data/test/manual_test.rb +0 -20
  39. data/test/new_relic_message_test.rb +0 -76
@@ -0,0 +1,67 @@
1
+ require 'test_helper'
2
+ require 'logger'
3
+
4
+ class ConnectionTest < Minitest::Test
5
+
6
+ def setup
7
+ @context = NewRelic::Binding::Context.new('license_key')
8
+ @connection = NewRelic::Binding::Connection.new(@context)
9
+ if NewRelic::Binding::Config.ssl_supported?
10
+ @endpoint = 'https://platform-api.newrelic.com'
11
+ else
12
+ @endpoint = 'http://platform-api.newrelic.com'
13
+ end
14
+ end
15
+
16
+ def test_deliver_successful
17
+ FakeWeb.register_uri(:post, "#{@endpoint}/platform/v1/metrics", :body => '{"status":"ok"}', :status => [200, "Success"])
18
+ ::Logger.expects(:info).never
19
+ assert_equal true, @connection.send_request('data')
20
+ end
21
+
22
+ def test_deliver_error_codes
23
+ FakeWeb.register_uri(:post, "#{@endpoint}/platform/v1/metrics", :body => '{"error":"Missing metric data"}', :status => [200, "Success"])
24
+ NewRelic::Logger.expects(:error).with("FAILED[200] <#{@endpoint}/platform/v1/metrics>: Missing metric data")
25
+ assert_equal false, @connection.send_request('data')
26
+ end
27
+
28
+ def test_deliver_disabled_by_new_relic
29
+ FakeWeb.register_uri(:post, "#{@endpoint}/platform/v1/metrics", :body => 'DISABLE_NEW_RELIC', :status => [403, 'Unauthorized'])
30
+ NewRelic::Logger.expects(:fatal).with("Agent has been disabled remotely by New Relic")
31
+ NewRelic::Binding::Connection.any_instance.expects(:abort)
32
+ @connection.send_request('data')
33
+ end
34
+
35
+ def test_deliver_no_response
36
+ Net::HTTP.any_instance.expects(:request).returns(nil)
37
+ NewRelic::Logger.expects(:error).with("FAILED: No response")
38
+ assert_equal false, @connection.send_request('data')
39
+ end
40
+
41
+ def test_deliver_no_data_returned
42
+ FakeWeb.register_uri(:post, "#{@endpoint}/platform/v1/metrics", :body => '', :status => [204, "No Content"])
43
+ NewRelic::Logger.expects(:error).with("FAILED[204] <#{@endpoint}/platform/v1/metrics>: no data returned")
44
+ assert_equal false, @connection.send_request('data')
45
+ end
46
+
47
+ def test_deliver_non_json_response_body_unexpected_response_code
48
+ FakeWeb.register_uri(:post, "#{@endpoint}/platform/v1/metrics", :body => 'test', :status => [203, "Non-Authoritative Information"])
49
+ JSON::ParserError.any_instance.stubs(:message => 'parse error')
50
+ NewRelic::Logger.expects(:error).with("FAILED[203] <#{@endpoint}/platform/v1/metrics>: Could not parse response: parse error")
51
+ assert_equal false, @connection.send_request('data')
52
+ end
53
+
54
+ def test_deliver_non_json_response_body_success_response_code
55
+ FakeWeb.register_uri(:post, "#{@endpoint}/platform/v1/metrics", :body => 'test', :status => [200, "Success"])
56
+ JSON::ParserError.any_instance.stubs(:message => 'parse error')
57
+ NewRelic::Logger.expects(:error).with("FAILED[200] <#{@endpoint}/platform/v1/metrics>: Could not parse response: parse error")
58
+ assert_equal false, @connection.send_request('data')
59
+ end
60
+
61
+ def test_deliver_service_unavailable
62
+ FakeWeb.register_uri(:post, "#{@endpoint}/platform/v1/metrics", :body => 'test', :status => [503, "Service Unavailable"])
63
+ NewRelic::Logger.expects(:warn).with("Collector temporarily unavailable. Continuing.")
64
+ assert_equal false, @connection.send_request('data')
65
+ end
66
+
67
+ end
@@ -0,0 +1,35 @@
1
+ require 'test_helper'
2
+
3
+ class ContextTest < Minitest::Test
4
+
5
+ def setup
6
+ @context = NewRelic::Binding::Context.new('license_key')
7
+ end
8
+
9
+ def test_that_create_component_returns_created_appointment
10
+ assert_equal NewRelic::Binding::Component, @context.create_component('name', 'com.test').class
11
+ end
12
+
13
+ def test_that_get_request_returns_a_request
14
+ assert_equal NewRelic::Binding::Request, @context.get_request.class
15
+ end
16
+
17
+ def test_that_get_request_returns_the_same_request_if_the_request_has_not_been_delivered
18
+ request = @context.get_request
19
+ assert_equal request, @context.get_request
20
+ end
21
+
22
+ def test_that_get_request_returns_a_new_request_if_the_aggregation_limit_is_reached
23
+ Timecop.freeze(Time.now - 25 * 60)
24
+ context = NewRelic::Binding::Context.new('license_key')
25
+ request = context.get_request
26
+ Timecop.return
27
+ assert request != context.get_request
28
+ end
29
+
30
+ def test_that_get_request_returns_a_new_request_if_the_request_has_been_delivered
31
+ request = @context.get_request
32
+ request.expects(:delivered?).returns(true)
33
+ assert request != @context.get_request
34
+ end
35
+ end
@@ -0,0 +1,33 @@
1
+ require 'test_helper'
2
+
3
+ class LoggerTest < Minitest::Test
4
+
5
+ def setup
6
+ @log = NewRelic::Logger.instance_variable_get(:@log)
7
+ end
8
+
9
+ def test_debug_calls_log_debug
10
+ @log.expects(:debug).with('test')
11
+ NewRelic::Logger.debug('test')
12
+ end
13
+
14
+ def test_info_calls_log_info
15
+ @log.expects(:info).with('test')
16
+ NewRelic::Logger.info('test')
17
+ end
18
+
19
+ def test_warn_calls_log_warn
20
+ @log.expects(:warn).with('test')
21
+ NewRelic::Logger.warn('test')
22
+ end
23
+
24
+ def test_error_calls_log_error
25
+ @log.expects(:error).with('test')
26
+ NewRelic::Logger.error('test')
27
+ end
28
+
29
+ def test_fatal_calls_log_fatal
30
+ @log.expects(:fatal).with('test')
31
+ NewRelic::Logger.fatal('test')
32
+ end
33
+ end
@@ -0,0 +1,97 @@
1
+ require 'test_helper'
2
+
3
+ class MetricTest < Minitest::Test
4
+
5
+ def setup
6
+ @component = NewRelic::Binding::Component.new('name', 'com.test')
7
+ end
8
+
9
+ def test_component
10
+ assert_equal @component, initialize_metric.component
11
+ end
12
+
13
+ def test_initialize_without_options_does_not_trigger_options_warning
14
+ NewRelic::Logger.expects(:warn).never
15
+ NewRelic::Binding::Metric.new(@component, 'Component/Test/rate[units]', '10')
16
+ end
17
+
18
+ def test_value
19
+ assert_equal 10, initialize_metric.value
20
+ end
21
+
22
+ def test_count_without_options
23
+ assert_equal 1, initialize_metric.count
24
+ end
25
+
26
+ def test_min_without_options
27
+ assert_equal 10, initialize_metric.min
28
+ end
29
+
30
+ def test_max_without_options
31
+ assert_equal 10, initialize_metric.max
32
+ end
33
+
34
+ def test_sum_of_squares_without_options
35
+ assert_equal 10*10, initialize_metric.sum_of_squares
36
+ end
37
+
38
+ def test_count_with_only_count_option_set
39
+ NewRelic::Logger.expects(:warn).with('Metric Component/Test/rate[units] count, min, max, and sum_of_squares are all required if one is set, falling back to value only')
40
+ assert_equal 1, initialize_metric(:count => 2).count
41
+ end
42
+
43
+ def test_min_with_only_min_option_set
44
+ NewRelic::Logger.expects(:warn).with('Metric Component/Test/rate[units] count, min, max, and sum_of_squares are all required if one is set, falling back to value only')
45
+ assert_equal 10, initialize_metric(:min => 5).min
46
+ end
47
+
48
+ def test_max_with_only_max_option_set
49
+ NewRelic::Logger.expects(:warn).with('Metric Component/Test/rate[units] count, min, max, and sum_of_squares are all required if one is set, falling back to value only')
50
+ assert_equal 10, initialize_metric(:max => 15).max
51
+ end
52
+
53
+ def test_sum_of_squares_with_only_sum_of_squares_option_set
54
+ NewRelic::Logger.expects(:warn).with('Metric Component/Test/rate[units] count, min, max, and sum_of_squares are all required if one is set, falling back to value only')
55
+ assert_equal 100, initialize_metric(:sum_of_squares => 400).sum_of_squares
56
+ end
57
+
58
+ def test_hash
59
+ assert_equal expected_hash, initialize_metric(:count => 2, :max => 15, :min => 5, :sum_of_squares => 250).to_hash
60
+ end
61
+
62
+ def test_initialize_with_string_for_value
63
+ metric = NewRelic::Binding::Metric.new(@component, 'Component/Test/rate[units]', '10')
64
+ hash = { 'Component/Test/rate[units]' => [10.0, 1, 10.0, 10.0, 100.0] }
65
+ assert_equal hash, metric.to_hash
66
+ end
67
+
68
+ def test_initialize_with_string_for_value_and_options
69
+ metric = NewRelic::Binding::Metric.new(@component, 'Component/Test/rate[units]', '10', :count => '2', :max => '15', :min => '5', :sum_of_squares => '250')
70
+ hash = { 'Component/Test/rate[units]' => [10.0, 2, 5.0, 15.0, 250.0] }
71
+ assert_equal hash, metric.to_hash
72
+ end
73
+
74
+ def test_aggregate_with_value
75
+ metric = initialize_metric()
76
+ metric2 = NewRelic::Binding::Metric.new(@component, 'Component/Test/rate[units]', 15)
77
+ metric.aggregate(metric2)
78
+ hash = { 'Component/Test/rate[units]' => [25.0, 2, 10.0, 15.0, 325.0] }
79
+ assert_equal hash, metric.to_hash
80
+ end
81
+
82
+ def test_aggregate_with_value_and_options
83
+ metric = initialize_metric()
84
+ metric2 = NewRelic::Binding::Metric.new(@component, 'Component/Test/rate[units]', '20', :count => '2', :max => '15', :min => '5', :sum_of_squares => '250')
85
+ metric.aggregate(metric2)
86
+ hash = { 'Component/Test/rate[units]' => [30.0, 3, 5.0, 15.0, 350.0] }
87
+ assert_equal hash, metric.to_hash
88
+ end
89
+
90
+ def initialize_metric(options = {})
91
+ NewRelic::Binding::Metric.new(@component, 'Component/Test/rate[units]', 10, options)
92
+ end
93
+
94
+ def expected_hash
95
+ { 'Component/Test/rate[units]' => [10, 2, 5, 15, 250] }
96
+ end
97
+ end
@@ -0,0 +1,127 @@
1
+ require 'test_helper'
2
+ require 'fakeweb'
3
+
4
+ class RequestTest < Minitest::Test
5
+
6
+ def setup
7
+ FakeWeb.allow_net_connect = false
8
+ @context = NewRelic::Binding::Context.new('license_key')
9
+ end
10
+
11
+ def test_initialization
12
+ request = NewRelic::Binding::Request.new(@context)
13
+ assert_equal @context, request.context
14
+ end
15
+
16
+ def test_add_metric_returns_a_metric
17
+ metric_setup
18
+ @metric = @request.add_metric(@component, 'Component/test_name', 10)
19
+ assert_equal NewRelic::Binding::Metric, @metric.class
20
+ end
21
+
22
+ def test_add_metric_does_not_aggregate_when_metric_does_not_already_exist
23
+ metric_setup
24
+ NewRelic::Binding::Metric.any_instance.expects(:aggregate).never
25
+ @metric = @request.add_metric(@component, 'Component/test_name', 10)
26
+ end
27
+
28
+ def test_add_metric_aggregates_when_metric_already_exists
29
+ metric_setup
30
+ @metric = @request.add_metric(@component, 'Component/test_name', 10)
31
+ @metric.expects(:aggregate)
32
+ @request.add_metric(@component, 'Component/test_name', 10)
33
+ end
34
+
35
+ def test_find_metric_when_component_does_not_exist_yet
36
+ metric_setup
37
+ metric_name = 'Component/test_name'
38
+ assert_equal nil, @request.send(:find_metric, @component, metric_name)
39
+ end
40
+
41
+ def test_find_metric_when_metric_does_not_exist
42
+ metric_setup
43
+ metric_name = 'Component/test_name'
44
+ metric = @request.add_metric(@component, metric_name, 10)
45
+ assert_equal nil, @request.send(:find_metric, @component, metric_name + '/foo')
46
+ end
47
+
48
+ def test_find_metric_when_metric_already_exists
49
+ metric_setup
50
+ metric_name = 'Component/test_name'
51
+ metric = @request.add_metric(@component, metric_name, 10)
52
+ assert_equal metric, @request.send(:find_metric, @component, metric_name)
53
+ end
54
+
55
+ def test_before_adding_metric_the_requests_metrics_data_structure_is_empty
56
+ metric_setup
57
+ assert_equal Hash.new, @request.instance_variable_get(:@metrics)
58
+ end
59
+
60
+ def test_after_adding_metric_the_requests_metrics_data_structure_contains_expected_data
61
+ metric_setup
62
+ @metric = @request.add_metric(@component, 'Component/test_name', 10)
63
+ expected_hash = { 'namecom.test' => [@metric] }
64
+ assert_equal expected_hash, @request.instance_variable_get(:@metrics)
65
+ end
66
+
67
+ def test_build_request_data_structure
68
+ metric_setup
69
+ @request.add_metric(@component, 'Component/test/first[units]', 1)
70
+ @request.add_metric(@component, 'Component/test/second[units]', 2)
71
+ assert_equal example_hash, @request.send(:build_request_data_structure)
72
+ end
73
+
74
+ def test_build_request_data_structure_when_component_has_no_metrics
75
+ metric_setup
76
+ ::NewRelic::Logger.expects(:warn).with("Component with name \"name\" and guid \"com.test\" had no metrics")
77
+ @request.send(:build_request_data_structure)
78
+ end
79
+
80
+ def test_delivered_returns_false_after_initialization
81
+ metric_setup
82
+ assert_equal false, @request.delivered?
83
+ end
84
+
85
+ def test_delivered_returns_true_after_successful_delivery
86
+ metric_setup
87
+ Timecop.freeze(Time.now)
88
+ ::NewRelic::Binding::Connection.any_instance.expects(:send_request).returns(true)
89
+ @context.expects(:last_request_delivered_at=).with(Time.now)
90
+ @request.deliver
91
+ assert_equal true, @request.delivered?
92
+ Timecop.return
93
+ end
94
+
95
+ def test_delivered_returns_false_after_unsuccessful_delivery
96
+ metric_setup
97
+ ::NewRelic::Binding::Connection.any_instance.expects(:send_request).returns(false)
98
+ @request.deliver
99
+ assert_equal false, @request.delivered?
100
+ end
101
+
102
+ def example_hash
103
+ {
104
+ 'agent' => {
105
+ 'version' => '1.0.0'
106
+ },
107
+ 'components' => [
108
+ {
109
+ 'name' => 'name',
110
+ 'guid' => 'com.test',
111
+ 'duration' => 60,
112
+ 'metrics' => {
113
+ 'Component/test/first[units]' => [1, 1, 1, 1, 1],
114
+ 'Component/test/second[units]' => [2, 1, 2, 2, 4]
115
+ }
116
+ }
117
+ ]
118
+ }
119
+ end
120
+
121
+ def metric_setup
122
+ @context.version = '1.0.0'
123
+ @component = @context.create_component('name', 'com.test')
124
+ @request = @context.get_request()
125
+ end
126
+
127
+ end
@@ -0,0 +1,127 @@
1
+ require 'test_helper'
2
+
3
+ class AgentTest < Minitest::Test
4
+
5
+ def setup
6
+ @agent_class = TestingAgent::Agent.dup
7
+ @context = NewRelic::Binding::Context.new('license_key')
8
+ end
9
+
10
+ def test_agent_guid_should_set_guid
11
+ @agent_class.class_eval do
12
+ agent_guid '12234'
13
+ end
14
+ agent = @agent_class.new(@context)
15
+ assert_equal '12234', agent.class.guid
16
+ end
17
+
18
+ def test_agent_guid_should_raise_if_guid_is_set_to_nil
19
+ assert_raises RuntimeError do
20
+ @agent_class.class_eval do
21
+ agent_guid nil
22
+ end
23
+ end
24
+ end
25
+
26
+ def test_agent_guid_should_raise_if_guid_is_set_to_empty_string
27
+ assert_raises RuntimeError do
28
+ @agent_class.class_eval do
29
+ agent_guid ""
30
+ end
31
+ end
32
+ end
33
+
34
+ def test_guid_should_return_instance_guid
35
+ agent = @agent_class.new(@context)
36
+ agent.instance_variable_set(:@guid, 'test')
37
+ assert_equal 'test', agent.guid
38
+ end
39
+
40
+ def test_guid_should_return_class_guid
41
+ @agent_class.class_eval do
42
+ @guid = '123'
43
+ end
44
+ agent = @agent_class.new(@context)
45
+ assert_equal '123', agent.guid
46
+ end
47
+
48
+ def test_agent_version_should_set_version
49
+ @agent_class.class_eval do
50
+ agent_version '0.0.1'
51
+ end
52
+ agent = @agent_class.new(@context)
53
+ assert_equal '0.0.1', agent.class.version
54
+ end
55
+
56
+ def test_agent_class_should_return_class_version
57
+ @agent_class.class_eval do
58
+ @version = '1.2.3'
59
+ end
60
+ agent = @agent_class.new(@context)
61
+ assert_equal '1.2.3', agent.version
62
+ end
63
+
64
+ def test_agent_human_labels_should_set_class_label
65
+ @agent_class.class_eval do
66
+ agent_human_labels('Testing Agent') { 'Testing Agent block' }
67
+ end
68
+ agent = @agent_class.new(@context)
69
+ assert_equal 'Testing Agent', agent.class.label
70
+ end
71
+
72
+ def test_agent_human_labels_should_set_instance_label_proc
73
+ @agent_class.class_eval do
74
+ agent_human_labels('Testing Agent') { 'Testing Agent block' }
75
+ end
76
+ agent = @agent_class.new(@context)
77
+ assert_equal "Testing Agent block", agent.class.instance_label_proc.call
78
+ end
79
+
80
+ def test_no_config_required_should_set_class_no_config_required
81
+ @agent_class.class_eval do
82
+ agent_human_labels('Testing Agent') { 'Testing Agent block' }
83
+ end
84
+ agent = @agent_class.new(@context)
85
+ assert_equal true, agent.class.no_config_required
86
+ end
87
+
88
+ def test_config_required_should_return_false_when_class_no_config_required_true
89
+ @agent_class.class_eval do
90
+ @no_config_required = true
91
+ end
92
+ agent = @agent_class.new(@context)
93
+ assert_equal false, agent.class.config_required?
94
+ end
95
+ def test_config_required_should_return_true_when_class_no_config_required_false
96
+ @agent_class.class_eval do
97
+ @no_config_required = false
98
+ end
99
+ agent = @agent_class.new(@context)
100
+ assert_equal true, agent.class.config_required?
101
+ end
102
+ def test_config_required_should_return_true_when_class_no_config_required_is_not_set
103
+ @agent_class.class_eval do
104
+ end
105
+ agent = @agent_class.new(@context)
106
+ assert_equal true, agent.class.config_required?
107
+ end
108
+
109
+ def test_agent_config_options_should_set_class_config_options_list_if_empty
110
+ @agent_class.class_eval do
111
+ agent_config_options(:test, 'foo', 'bar')
112
+ end
113
+ @agent = @agent_class.new(@context)
114
+ assert_equal [:test, 'foo', 'bar'], @agent.class.config_options_list
115
+ end
116
+
117
+ def test_agent_config_options_should_add_to_existing_config_options_list
118
+ @agent_class.class_eval do
119
+ attr_accessor 'foobar'
120
+ @config_options_list = ['foobar']
121
+ agent_config_options(:test, 'foo', 'bar')
122
+ end
123
+
124
+ @agent = @agent_class.new(@context)
125
+ assert_equal ['foobar', :test, 'foo', 'bar'], @agent.class.config_options_list
126
+ end
127
+ end