appsignal 0.11.18 → 0.12.beta.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. data/.gitignore +6 -0
  2. data/CHANGELOG.md +4 -38
  3. data/Rakefile +14 -6
  4. data/appsignal.gemspec +3 -1
  5. data/benchmark.rake +12 -16
  6. data/ext/appsignal_extension.c +183 -0
  7. data/ext/extconf.rb +39 -0
  8. data/gemfiles/capistrano2.gemfile +0 -1
  9. data/gemfiles/capistrano3.gemfile +0 -1
  10. data/gemfiles/rails-4.2.gemfile +1 -1
  11. data/lib/appsignal.rb +23 -61
  12. data/lib/appsignal/capistrano.rb +1 -2
  13. data/lib/appsignal/config.rb +13 -1
  14. data/lib/appsignal/event_formatter.rb +67 -0
  15. data/lib/appsignal/event_formatter/action_view/render_formatter.rb +23 -0
  16. data/lib/appsignal/event_formatter/active_record/sql_formatter.rb +74 -0
  17. data/lib/appsignal/event_formatter/moped/query_formatter.rb +80 -0
  18. data/lib/appsignal/event_formatter/net_http/request_formatter.rb +13 -0
  19. data/lib/appsignal/instrumentations/net_http.rb +6 -4
  20. data/lib/appsignal/integrations/resque.rb +2 -10
  21. data/lib/appsignal/integrations/sidekiq.rb +2 -2
  22. data/lib/appsignal/integrations/sinatra.rb +1 -0
  23. data/lib/appsignal/js_exception_transaction.rb +44 -28
  24. data/lib/appsignal/marker.rb +11 -13
  25. data/lib/appsignal/params_sanitizer.rb +5 -8
  26. data/lib/appsignal/rack/instrumentation.rb +2 -0
  27. data/lib/appsignal/rack/js_exception_catcher.rb +1 -0
  28. data/lib/appsignal/rack/listener.rb +1 -1
  29. data/lib/appsignal/rack/sinatra_instrumentation.rb +2 -12
  30. data/lib/appsignal/subscriber.rb +59 -0
  31. data/lib/appsignal/transaction.rb +117 -174
  32. data/lib/appsignal/transmitter.rb +8 -37
  33. data/lib/appsignal/version.rb +2 -1
  34. data/spec/lib/appsignal/config_spec.rb +25 -4
  35. data/spec/lib/appsignal/event_formatter/action_view/render_formatter_spec.rb +42 -0
  36. data/spec/lib/appsignal/{aggregator/middleware/active_record_sanitizer_spec.rb → event_formatter/active_record/sql_formatter_spec.rb} +61 -61
  37. data/spec/lib/appsignal/{event/moped_event_spec.rb → event_formatter/moped/query_formatter_spec.rb} +32 -78
  38. data/spec/lib/appsignal/event_formatter/net_http/request_formatter_spec.rb +26 -0
  39. data/spec/lib/appsignal/event_formatter_spec.rb +102 -0
  40. data/spec/lib/appsignal/extension_spec.rb +75 -0
  41. data/spec/lib/appsignal/instrumentations/net_http_spec.rb +20 -4
  42. data/spec/lib/appsignal/integrations/delayed_job_spec.rb +3 -2
  43. data/spec/lib/appsignal/integrations/rails_spec.rb +0 -7
  44. data/spec/lib/appsignal/integrations/resque_spec.rb +51 -55
  45. data/spec/lib/appsignal/integrations/sequel_spec.rb +8 -3
  46. data/spec/lib/appsignal/integrations/sidekiq_spec.rb +4 -21
  47. data/spec/lib/appsignal/integrations/sinatra_spec.rb +0 -6
  48. data/spec/lib/appsignal/js_exception_transaction_spec.rb +57 -60
  49. data/spec/lib/appsignal/params_sanitizer_spec.rb +11 -27
  50. data/spec/lib/appsignal/rack/listener_spec.rb +6 -6
  51. data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +2 -43
  52. data/spec/lib/appsignal/subscriber_spec.rb +162 -0
  53. data/spec/lib/appsignal/transaction_spec.rb +283 -615
  54. data/spec/lib/appsignal/transmitter_spec.rb +3 -32
  55. data/spec/lib/appsignal_spec.rb +41 -90
  56. data/spec/lib/generators/appsignal/appsignal_generator_spec.rb +0 -17
  57. data/spec/spec_helper.rb +18 -22
  58. data/spec/support/helpers/notification_helpers.rb +1 -1
  59. data/spec/support/helpers/time_helpers.rb +11 -0
  60. data/spec/support/helpers/transaction_helpers.rb +6 -18
  61. data/spec/support/project_fixture/config/appsignal.yml +1 -2
  62. metadata +68 -78
  63. checksums.yaml +0 -7
  64. data/gemfiles/padrino-0.13.gemfile +0 -7
  65. data/gemfiles/resque.gemfile +0 -5
  66. data/lib/appsignal/agent.rb +0 -217
  67. data/lib/appsignal/aggregator.rb +0 -67
  68. data/lib/appsignal/aggregator/middleware.rb +0 -4
  69. data/lib/appsignal/aggregator/middleware/action_view_sanitizer.rb +0 -23
  70. data/lib/appsignal/aggregator/middleware/active_record_sanitizer.rb +0 -65
  71. data/lib/appsignal/aggregator/middleware/chain.rb +0 -101
  72. data/lib/appsignal/aggregator/middleware/delete_blanks.rb +0 -16
  73. data/lib/appsignal/aggregator/post_processor.rb +0 -32
  74. data/lib/appsignal/event.rb +0 -20
  75. data/lib/appsignal/event/moped_event.rb +0 -90
  76. data/lib/appsignal/integrations/padrino.rb +0 -64
  77. data/lib/appsignal/integrations/passenger.rb +0 -13
  78. data/lib/appsignal/integrations/rake.rb +0 -29
  79. data/lib/appsignal/integrations/unicorn.rb +0 -25
  80. data/lib/appsignal/ipc.rb +0 -68
  81. data/lib/appsignal/transaction/formatter.rb +0 -85
  82. data/lib/appsignal/transaction/params_sanitizer.rb +0 -4
  83. data/lib/appsignal/zipped_payload.rb +0 -37
  84. data/spec/lib/appsignal/agent_spec.rb +0 -592
  85. data/spec/lib/appsignal/aggregator/middleware/action_view_sanitizer_spec.rb +0 -44
  86. data/spec/lib/appsignal/aggregator/middleware/chain_spec.rb +0 -168
  87. data/spec/lib/appsignal/aggregator/middleware/delete_blanks_spec.rb +0 -37
  88. data/spec/lib/appsignal/aggregator/post_processor_spec.rb +0 -99
  89. data/spec/lib/appsignal/aggregator_spec.rb +0 -186
  90. data/spec/lib/appsignal/event_spec.rb +0 -48
  91. data/spec/lib/appsignal/integrations/padrino_spec.rb +0 -171
  92. data/spec/lib/appsignal/integrations/passenger_spec.rb +0 -22
  93. data/spec/lib/appsignal/integrations/rake_spec.rb +0 -92
  94. data/spec/lib/appsignal/integrations/unicorn_spec.rb +0 -48
  95. data/spec/lib/appsignal/ipc_spec.rb +0 -128
  96. data/spec/lib/appsignal/transaction/formatter_spec.rb +0 -247
  97. data/spec/lib/appsignal/zipped_payload_spec.rb +0 -42
@@ -30,7 +30,7 @@ module Appsignal
30
30
  end
31
31
 
32
32
  def uri
33
- @uri ||= URI("#{config[:endpoint]}/#{action}").tap do |uri|
33
+ @uri ||= URI("#{config[:endpoint]}/1/#{action}").tap do |uri|
34
34
  uri.query = ::Rack::Utils.build_query({
35
35
  :api_key => config[:push_api_key],
36
36
  :name => config[:name],
@@ -41,12 +41,7 @@ module Appsignal
41
41
  end
42
42
  end
43
43
 
44
- # Accepts a string or `Appsignal::ZippedPayload`
45
- # If no `Appsignal::ZippedPayload` is given, it will convert it to one.
46
44
  def transmit(payload)
47
- unless payload.is_a?(Appsignal::ZippedPayload)
48
- payload = Appsignal::ZippedPayload.new(payload)
49
- end
50
45
  Appsignal.logger.debug "Transmitting payload to #{uri}"
51
46
  http_client.request(http_post(payload)).code
52
47
  end
@@ -57,45 +52,21 @@ module Appsignal
57
52
  Net::HTTP::Post.new(uri.request_uri).tap do |request|
58
53
  request['Content-Type'] = CONTENT_TYPE
59
54
  request['Content-Encoding'] = CONTENT_ENCODING
60
- request.body = payload.body
55
+ request.body = Zlib::Deflate.deflate(
56
+ JSON.generate(payload, :quirks_mode => true),
57
+ Zlib::BEST_SPEED
58
+ )
61
59
  end
62
60
  end
63
61
 
64
62
  def http_client
65
- client = if config[:http_proxy]
66
- Net::HTTP.new(uri.host, uri.port, proxy_addr, proxy_port)
67
- else
68
- Net::HTTP.new(uri.host, uri.port)
69
- end
70
-
71
- client.tap do |http|
63
+ Net::HTTP.new(uri.host, uri.port).tap do |http|
72
64
  if uri.scheme == 'https'
73
- http.use_ssl = true
74
- http.ssl_version = :TLSv1
65
+ http.use_ssl = true
75
66
  http.verify_mode = OpenSSL::SSL::VERIFY_PEER
76
- http.ca_file = CA_FILE_PATH
67
+ http.ca_file = CA_FILE_PATH
77
68
  end
78
69
  end
79
70
  end
80
-
81
- def proxy_uri
82
- @proxy_uri ||= URI.parse(config[:http_proxy])
83
- end
84
-
85
- def proxy_addr
86
- if config[:http_proxy]
87
- proxy_uri.host
88
- else
89
- nil
90
- end
91
- end
92
-
93
- def proxy_port
94
- if config[:http_proxy]
95
- proxy_uri.port
96
- else
97
- nil
98
- end
99
- end
100
71
  end
101
72
  end
@@ -1,3 +1,4 @@
1
1
  module Appsignal
2
- VERSION = '0.11.18'
2
+ VERSION = '0.12.beta.0'
3
+ AGENT_VERSION = 'eea0fcb'
3
4
  end
@@ -21,7 +21,7 @@ describe Appsignal::Config do
21
21
  :instrument_net_http => true,
22
22
  :skip_session_data => false,
23
23
  :send_params => true,
24
- :endpoint => 'https://push.appsignal.com/1',
24
+ :endpoint => 'https://push.appsignal.com',
25
25
  :slow_request_threshold => 200,
26
26
  :push_api_key => 'abc',
27
27
  :name => 'TestApp',
@@ -41,6 +41,24 @@ describe Appsignal::Config do
41
41
  end
42
42
  end
43
43
 
44
+ describe "#write_to_environment" do
45
+ before do
46
+ subject.write_to_environment
47
+ end
48
+
49
+ it "should write the current config to env vars" do
50
+ ENV['APPSIGNAL_ACTIVE'].should == 'true'
51
+ ENV['APPSIGNAL_APP_PATH'].should end_with('spec/support/project_fixture')
52
+ ENV['APPSIGNAL_AGENT_PATH'].should end_with('/ext')
53
+ ENV['APPSIGNAL_LOG_PATH'].should end_with('/log')
54
+ ENV['APPSIGNAL_PUSH_API_ENDPOINT'].should == 'https://push.appsignal.com'
55
+ ENV['APPSIGNAL_PUSH_API_KEY'].should == 'abc'
56
+ ENV['APPSIGNAL_APP_NAME'].should == 'TestApp'
57
+ ENV['APPSIGNAL_ENVIRONMENT'].should == 'production'
58
+ ENV['APPSIGNAL_AGENT_VERSION'].should == Appsignal::AGENT_VERSION
59
+ end
60
+ end
61
+
44
62
  context "if the env is passed as a symbol" do
45
63
  let(:config) { project_fixture_config(:production) }
46
64
 
@@ -63,7 +81,6 @@ describe Appsignal::Config do
63
81
  it "should merge with the config" do
64
82
  subject[:name].should == 'TestApp'
65
83
  subject[:initial_key].should == 'value'
66
- subject[:ignore_exceptions].should == []
67
84
  end
68
85
  end
69
86
 
@@ -91,6 +108,11 @@ describe Appsignal::Config do
91
108
  end
92
109
 
93
110
  context "when there is no config file" do
111
+ before do
112
+ ENV.keys.select { |key| key.start_with?('APPSIGNAL_') }.each do |key|
113
+ ENV[key] = nil
114
+ end
115
+ end
94
116
  let(:initial_config) { {} }
95
117
  let(:config) { Appsignal::Config.new('/nothing', 'production', initial_config) }
96
118
 
@@ -136,7 +158,7 @@ describe Appsignal::Config do
136
158
  :send_params => true,
137
159
  :instrument_net_http => true,
138
160
  :skip_session_data => false,
139
- :endpoint => 'https://push.appsignal.com/1',
161
+ :endpoint => 'https://push.appsignal.com',
140
162
  :slow_request_threshold => 200,
141
163
  :active => true,
142
164
  :enable_frontend_error_catching => false,
@@ -150,7 +172,6 @@ describe Appsignal::Config do
150
172
  it "should merge with the config" do
151
173
  Appsignal.logger.should_not_receive(:debug)
152
174
  subject[:name].should == 'Initial Name'
153
- subject[:ignore_exceptions].should == []
154
175
  end
155
176
  end
156
177
 
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ if rails_present?
4
+ require 'action_view'
5
+
6
+ describe Appsignal::EventFormatter::ActionView::RenderFormatter do
7
+ before { Rails.root.stub(:to_s => '/var/www/app/20130101') }
8
+ let(:klass) { Appsignal::EventFormatter::ActionView::RenderFormatter }
9
+ let(:formatter) { klass.new }
10
+
11
+ it "should register render_partial.action_view and render_template.action_view" do
12
+ Appsignal::EventFormatter.registered?('render_partial.action_view', klass).should be_true
13
+ Appsignal::EventFormatter.registered?('render_template.action_view', klass).should be_true
14
+ end
15
+
16
+ describe "#root_path" do
17
+ its(:root_path) { should == '/var/www/app/20130101/' }
18
+ end
19
+
20
+ describe "#format" do
21
+ subject { formatter.format(payload) }
22
+
23
+ context "with an identifier" do
24
+ let(:payload) { {:identifier => '/var/www/app/20130101/app/views/home/index/html.erb'} }
25
+
26
+ it { should == ['app/views/home/index/html.erb', nil] }
27
+ end
28
+
29
+ context "with a frozen identifier" do
30
+ let(:payload) { {:identifier => '/var/www/app/20130101/app/views/home/index/html.erb'.freeze} }
31
+
32
+ it { should == ['app/views/home/index/html.erb', nil] }
33
+ end
34
+
35
+ context "without an identifier" do
36
+ let(:payload) { {} }
37
+
38
+ it { should be_nil }
39
+ end
40
+ end
41
+ end
42
+ end
@@ -1,12 +1,11 @@
1
1
  require 'spec_helper'
2
2
 
3
- if active_record_present?
3
+ if rails_present?
4
4
  require 'active_record'
5
- require 'appsignal/aggregator/middleware/active_record_sanitizer'
6
5
 
7
- describe Appsignal::Aggregator::Middleware::ActiveRecordSanitizer do
8
- let(:klass) { Appsignal::Aggregator::Middleware::ActiveRecordSanitizer }
9
- let(:sql_event_sanitizer) { klass.new }
6
+ describe Appsignal::EventFormatter::ActiveRecord::SqlFormatter do
7
+ let(:klass) { Appsignal::EventFormatter::ActiveRecord::SqlFormatter }
8
+ let(:formatter) { klass.new }
10
9
  let(:connection_config) { {} }
11
10
  before do
12
11
  if ActiveRecord::Base.respond_to?(:connection_config)
@@ -23,80 +22,82 @@ if active_record_present?
23
22
  end
24
23
  end
25
24
 
26
- describe "#call" do
27
- let(:name) { 'Model load' }
28
- let(:binds) { [] }
29
- let(:event) do
30
- notification_event(
31
- :name => 'sql.active_record',
32
- :payload => create_payload(
33
- :name => name,
34
- :sql => sql,
35
- :binds => binds,
36
- :connection_id => 1111
37
- )
38
- )
25
+ pending "should register sql.activerecord" do
26
+ Appsignal::EventFormatter.registered?('sql.active_record', klass).should be_true
27
+ end
28
+
29
+ context "if a connection cannot be established" do
30
+ before do
31
+ ActiveRecord::Base.stub(:connection_config).and_raise(ActiveRecord::ConnectionNotEstablished)
39
32
  end
40
- subject { event.payload[:sql] }
41
- before { sql_event_sanitizer.call(event) { } }
42
33
 
43
- context "connection id and bindings" do
44
- let(:sql) { '' }
45
- subject { event.payload }
34
+ it "should log the error and unregister the formatter" do
35
+ Appsignal.logger.should_receive(:error).with(
36
+ 'Error while getting ActiveRecord connection info, unregistering sql.active_record event formatter'
37
+ )
38
+
39
+ lambda {
40
+ formatter
41
+ }.should_not raise_error
46
42
 
47
- it { should_not have_key(:connection_id) }
48
- it { should_not have_key(:binds) }
43
+ Appsignal::EventFormatter.registered?('sql.active_record').should be_false
49
44
  end
45
+ end
46
+
47
+ describe "#format" do
48
+ let(:name) { 'Model load' }
49
+ let(:payload) { {:sql => sql, :name => name} }
50
+ subject { formatter.format(payload) }
50
51
 
51
52
  context "with backtick table names" do
52
- before { sql_event_sanitizer.stub(:adapter_uses_double_quoted_table_names? => false) }
53
+ before { formatter.stub(:adapter_uses_double_quoted_table_names => false) }
53
54
 
54
55
  context "single quoted data value" do
55
56
  let(:sql) { "SELECT `table`.* FROM `table` WHERE `id` = 'secret'" }
56
57
 
57
- it { should == "SELECT `table`.* FROM `table` WHERE `id` = ?" }
58
+ it { should == ['Model load', "SELECT `table`.* FROM `table` WHERE `id` = ?"] }
58
59
 
59
60
  context "with an escaped single quote" do
60
61
  let(:sql) { "`id` = '\\'big\\' secret'" }
61
62
 
62
- it { should == "`id` = ?" }
63
+ it { should == ['Model load', "`id` = ?"] }
63
64
  end
64
65
 
65
66
  context "with an escaped double quote" do
66
67
  let(:sql) { "`id` = '\\\"big\\\" secret'" }
67
68
 
68
- it { should == "`id` = ?" }
69
+ it { should == ['Model load', "`id` = ?"] }
69
70
  end
70
71
  end
71
72
 
72
73
  context "double quoted data value" do
73
74
  let(:sql) { 'SELECT `table`.* FROM `table` WHERE `id` = "secret"' }
74
75
 
75
- it { should == 'SELECT `table`.* FROM `table` WHERE `id` = ?' }
76
+ it { should == ['Model load', 'SELECT `table`.* FROM `table` WHERE `id` = ?'] }
76
77
 
77
78
  context "with an escaped single quote" do
78
79
  let(:sql) { '`id` = "\\\'big\\\' secret"' }
79
80
 
80
- it { should == "`id` = ?" }
81
+ it { should == ['Model load', "`id` = ?"] }
81
82
  end
82
83
 
83
84
  context "with an escaped double quote" do
84
85
  let(:sql) { '`id` = "\\"big\\" secret"' }
85
86
 
86
- it { should == "`id` = ?" }
87
+ it { should == ['Model load', "`id` = ?"] }
87
88
  end
88
89
  end
89
90
 
90
91
  context "numeric parameter" do
91
92
  let(:sql) { 'SELECT `table`.* FROM `table` WHERE `id` = 1' }
92
93
 
93
- it { should == 'SELECT `table`.* FROM `table` WHERE `id` = ?' }
94
+ it { should == ['Model load', 'SELECT `table`.* FROM `table` WHERE `id` = ?'] }
94
95
  end
95
96
 
96
97
  context "parameter array" do
97
98
  let(:sql) { 'SELECT `table`.* FROM `table` WHERE `id` IN (1, 2)' }
98
99
 
99
- it { should == 'SELECT `table`.* FROM `table` WHERE `id` IN (?)' }
100
+ it { should == ['Model load', 'SELECT `table`.* FROM `table` WHERE `id` IN (?)'] }
100
101
  end
101
102
  end
102
103
 
@@ -106,25 +107,25 @@ if active_record_present?
106
107
  context "single quoted data value" do
107
108
  let(:sql) { "SELECT \"table\".* FROM \"table\" WHERE \"id\" = 'secret'" }
108
109
 
109
- it { should == "SELECT \"table\".* FROM \"table\" WHERE \"id\" = ?" }
110
+ it { should == ['Model load', "SELECT \"table\".* FROM \"table\" WHERE \"id\" = ?"] }
110
111
 
111
112
  context "with an escaped single quote" do
112
113
  let(:sql) { "\"id\" = '\\'big\\' secret'" }
113
114
 
114
- it { should == "\"id\" = ?" }
115
+ it { should == ['Model load', "\"id\" = ?"] }
115
116
  end
116
117
 
117
118
  context "with an escaped double quote" do
118
119
  let(:sql) { "\"id\" = '\\\"big\\\" secret'" }
119
120
 
120
- it { should == "\"id\" = ?" }
121
+ it { should == ['Model load', "\"id\" = ?"] }
121
122
  end
122
123
  end
123
124
 
124
125
  context "numeric parameter" do
125
126
  let(:sql) { 'SELECT "table".* FROM "table" WHERE "id"=1' }
126
127
 
127
- it { should == 'SELECT "table".* FROM "table" WHERE "id"=?' }
128
+ it { should == ['Model load', 'SELECT "table".* FROM "table" WHERE "id"=?'] }
128
129
  end
129
130
  end
130
131
 
@@ -133,27 +134,26 @@ if active_record_present?
133
134
 
134
135
  let(:sql) { 'SELECT "table".* FROM "table" WHERE "id"=$1' }
135
136
 
136
- it { should == 'SELECT "table".* FROM "table" WHERE "id"=$1' }
137
+ it { should == ['Model load', 'SELECT "table".* FROM "table" WHERE "id"=$1'] }
137
138
  end
138
139
 
139
- context "skip sanitization for schema queries" do
140
+ context "return nil for schema queries" do
140
141
  let(:name) { 'SCHEMA' }
141
142
  let(:sql) { 'SET client_min_messages TO 22' }
142
143
 
143
- it { should == 'SET client_min_messages TO 22' }
144
+ it { should be_nil }
144
145
  end
145
146
 
146
147
  context "with a a frozen sql string" do
147
148
  let(:sql) { "SELECT `table`.* FROM `table` WHERE `id` = 'secret'".freeze }
148
149
 
149
- it { should == "SELECT `table`.* FROM `table` WHERE `id` = ?" }
150
+ it { should == ['Model load', "SELECT `table`.* FROM `table` WHERE `id` = ?"] }
150
151
  end
151
152
  end
152
153
 
153
154
  describe "#schema_query?" do
154
155
  let(:payload) { {} }
155
- let(:event) { notification_event(:payload => payload) }
156
- subject { sql_event_sanitizer.schema_query?(event) }
156
+ subject { formatter.send(:schema_query?, payload) }
157
157
 
158
158
  it { should be_false }
159
159
 
@@ -168,13 +168,13 @@ if active_record_present?
168
168
  describe "#connection_config" do
169
169
  let(:connection_config) { {:adapter => 'adapter'} }
170
170
 
171
- subject { sql_event_sanitizer.connection_config }
171
+ subject { formatter.send(:connection_config) }
172
172
 
173
173
  it { should == {:adapter => 'adapter'} }
174
174
  end
175
175
 
176
- describe "#adapter_uses_double_quoted_table_names?" do
177
- subject { sql_event_sanitizer.adapter_uses_double_quoted_table_names? }
176
+ describe "#adapter_uses_double_quoted_table_names" do
177
+ subject { formatter.adapter_uses_double_quoted_table_names }
178
178
 
179
179
  context "when using mysql" do
180
180
  let(:connection_config) { {:adapter => 'mysql'} }
@@ -193,27 +193,27 @@ if active_record_present?
193
193
 
194
194
  it { should be_true }
195
195
  end
196
- end
197
196
 
198
- describe "adapter_uses_prepared_statements?" do
199
- subject { sql_event_sanitizer.adapter_uses_prepared_statements? }
197
+ describe "adapter_uses_prepared_statements" do
198
+ subject { formatter.adapter_uses_prepared_statements }
200
199
 
201
- context "when using mysql" do
202
- let(:connection_config) { {:adapter => 'mysql'} }
200
+ context "when using mysql" do
201
+ let(:connection_config) { {:adapter => 'mysql'} }
203
202
 
204
- it { should be_false }
205
- end
203
+ it { should be_false }
204
+ end
206
205
 
207
- context "when using postgresql" do
208
- let(:connection_config) { {:adapter => 'postgresql'} }
206
+ context "when using postgresql" do
207
+ let(:connection_config) { {:adapter => 'postgresql'} }
209
208
 
210
- it { should be_true }
211
- end
209
+ it { should be_true }
210
+ end
212
211
 
213
- context "when using postgresql and prepared statements is disabled" do
214
- let(:connection_config) { {:adapter => 'postgresql', :prepared_statements => false} }
212
+ context "when using postgresql and prepared statements is disabled" do
213
+ let(:connection_config) { {:adapter => 'postgresql', :prepared_statements => false} }
215
214
 
216
- it { should be_false }
215
+ it { should be_false }
216
+ end
217
217
  end
218
218
  end
219
219
  end
@@ -1,23 +1,25 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Appsignal::Event::MopedEvent do
4
- let(:event) do
5
- Appsignal::Event::MopedEvent.new('query.moped', 1, 2, 123, {})
3
+ describe Appsignal::EventFormatter::Moped::QueryFormatter do
4
+ let(:klass) { Appsignal::EventFormatter::Moped::QueryFormatter }
5
+ let(:formatter) { klass.new }
6
+
7
+ it "should register query.moped" do
8
+ Appsignal::EventFormatter.registered?('query.moped', klass).should be_true
6
9
  end
7
10
 
8
- describe "#transform_payload" do
9
- before { event.stub(:payload_from_op => {'foo' => 'bar'}) }
11
+ describe "#format" do
12
+ let(:payload) { {:ops => [op]} }
13
+ subject { formatter.format(payload) }
14
+
15
+ context "without ops in the payload" do
16
+ let(:payload) { {} }
10
17
 
11
- it "should map the operations to a normalized payload" do
12
- expect( event.transform_payload(:ops => [{}]) ).to eq(
13
- :ops => [{'foo' => 'bar'}]
14
- )
18
+ it { should be_nil }
15
19
  end
16
- end
17
20
 
18
- describe "#payload_from_op" do
19
- context "Moped::Protocol::Query" do
20
- let(:payload) do
21
+ context "Moped::Protocol::Command" do
22
+ let(:op) do
21
23
  double(
22
24
  :full_collection_name => 'database.collection',
23
25
  :selector => {'_id' => 'abc'},
@@ -25,17 +27,11 @@ describe Appsignal::Event::MopedEvent do
25
27
  )
26
28
  end
27
29
 
28
- it "should transform the payload" do
29
- expect( event.payload_from_op(payload) ).to eq(
30
- :type => "Command",
31
- :database => "database.collection",
32
- :selector => {"_id" => "?"}
33
- )
34
- end
30
+ it { should == ['Command', '{:database=>"database.collection", :selector=>{"_id"=>"?"}}'] }
35
31
  end
36
32
 
37
33
  context "Moped::Protocol::Query" do
38
- let(:payload) do
34
+ let(:op) do
39
35
  double(
40
36
  :full_collection_name => 'database.collection',
41
37
  :selector => {'_id' => 'abc'},
@@ -47,21 +43,11 @@ describe Appsignal::Event::MopedEvent do
47
43
  )
48
44
  end
49
45
 
50
- it "should transform the payload" do
51
- expect( event.payload_from_op(payload) ).to eq(
52
- :type => "Query",
53
- :database => "database.collection",
54
- :selector => {"_id" => "?"},
55
- :flags => [],
56
- :limit => 0,
57
- :skip => 0,
58
- :fields => nil,
59
- )
60
- end
46
+ it { should == ['Query', '{:database=>"database.collection", :selector=>{"_id"=>"?"}, :flags=>[], :limit=>0, :skip=>0, :fields=>nil}'] }
61
47
  end
62
48
 
63
49
  context "Moped::Protocol::Delete" do
64
- let(:payload) do
50
+ let(:op) do
65
51
  double(
66
52
  :full_collection_name => 'database.collection',
67
53
  :selector => {'_id' => 'abc'},
@@ -70,18 +56,11 @@ describe Appsignal::Event::MopedEvent do
70
56
  )
71
57
  end
72
58
 
73
- it "should transform the payload" do
74
- expect( event.payload_from_op(payload) ).to eq(
75
- :type => "Delete",
76
- :database => "database.collection",
77
- :selector => {"_id" => "?"},
78
- :flags => []
79
- )
80
- end
59
+ it { should == ['Delete', '{:database=>"database.collection", :selector=>{"_id"=>"?"}, :flags=>[]}'] }
81
60
  end
82
61
 
83
62
  context "Moped::Protocol::Insert" do
84
- let(:payload) do
63
+ let(:op) do
85
64
  double(
86
65
  :full_collection_name => 'database.collection',
87
66
  :flags => [],
@@ -90,18 +69,11 @@ describe Appsignal::Event::MopedEvent do
90
69
  )
91
70
  end
92
71
 
93
- it "should transform the payload" do
94
- expect( event.payload_from_op(payload) ).to eq(
95
- :type => "Insert",
96
- :database => "database.collection",
97
- :flags => [],
98
- :documents => [{"_id" => "?"}, {"_id" => "?"}]
99
- )
100
- end
72
+ it { should == ['Insert', '{:database=>"database.collection", :documents=>[{"_id"=>"?"}, {"_id"=>"?"}], :flags=>[]}'] }
101
73
  end
102
74
 
103
75
  context "Moped::Protocol::Update" do
104
- let(:payload) do
76
+ let(:op) do
105
77
  double(
106
78
  :full_collection_name => 'database.collection',
107
79
  :selector => {'_id' => 'abc'},
@@ -111,47 +83,29 @@ describe Appsignal::Event::MopedEvent do
111
83
  )
112
84
  end
113
85
 
114
- it "should transform the payload" do
115
- expect( event.payload_from_op(payload) ).to eq(
116
- :type => "Update",
117
- :database => "database.collection",
118
- :selector => {"_id" => "?"},
119
- :update => {"name" => "?"},
120
- :flags => []
121
- )
122
- end
86
+ it { should == ['Update', '{:database=>"database.collection", :selector=>{"_id"=>"?"}, :update=>{"name"=>"?"}, :flags=>[]}'] }
123
87
  end
124
88
 
125
89
  context "Moped::Protocol::KillCursors" do
126
- let(:payload) do
90
+ let(:op) do
127
91
  double(
128
92
  :number_of_cursor_ids => 2,
129
93
  :class => double(:to_s => 'Moped::Protocol::KillCursors')
130
94
  )
131
95
  end
132
96
 
133
- it "should transform the payload" do
134
- expect( event.payload_from_op(payload) ).to eq(
135
- :type => "KillCursors",
136
- :number_of_cursor_ids => 2
137
- )
138
- end
97
+ it { should == ['KillCursors', '{:number_of_cursor_ids=>2}'] }
139
98
  end
140
99
 
141
100
  context "Moped::Protocol::Other" do
142
- let(:payload) do
101
+ let(:op) do
143
102
  double(
144
103
  :full_collection_name => 'database.collection',
145
104
  :class => double(:to_s => 'Moped::Protocol::Other')
146
105
  )
147
106
  end
148
107
 
149
- it "should transform the payload" do
150
- expect( event.payload_from_op(payload) ).to eq(
151
- :type => "Other",
152
- :database => "database.collection"
153
- )
154
- end
108
+ it { should == ['Other', '{:database=>"database.collection"}'] }
155
109
  end
156
110
  end
157
111
 
@@ -160,7 +114,7 @@ describe Appsignal::Event::MopedEvent do
160
114
  let(:params) { {'foo' => 'bar'} }
161
115
 
162
116
  it "should sanitize all hash values with a questionmark" do
163
- expect( event.sanitize(params) ).to eq('foo' => '?')
117
+ expect( formatter.send(:sanitize, params) ).to eq('foo' => '?')
164
118
  end
165
119
  end
166
120
 
@@ -168,7 +122,7 @@ describe Appsignal::Event::MopedEvent do
168
122
  let(:params) { [{'foo' => 'bar'}] }
169
123
 
170
124
  it "should sanitize all hash values with a questionmark" do
171
- expect( event.sanitize(params) ).to eq([{'foo' => '?'}])
125
+ expect( formatter.send(:sanitize, params) ).to eq([{'foo' => '?'}])
172
126
  end
173
127
  end
174
128
 
@@ -176,14 +130,14 @@ describe Appsignal::Event::MopedEvent do
176
130
  let(:params) { ['foo', 'bar'] }
177
131
 
178
132
  it "should sanitize all hash values with a single questionmark" do
179
- expect( event.sanitize(params) ).to eq(['?'])
133
+ expect( formatter.send(:sanitize, params) ).to eq(['?'])
180
134
  end
181
135
  end
182
136
  context "when params is a string" do
183
137
  let(:params) { 'bar'}
184
138
 
185
139
  it "should sanitize all hash values with a questionmark" do
186
- expect( event.sanitize(params) ).to eq('?')
140
+ expect( formatter.send(:sanitize, params) ).to eq('?')
187
141
  end
188
142
  end
189
143
  end