newrelic_plugin 1.0.3 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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