appoptics_apm 4.0.2

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 (226) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +43 -0
  3. data/.dockerignore +5 -0
  4. data/.gitignore +23 -0
  5. data/.rubocop.yml +5 -0
  6. data/.travis.yml +82 -0
  7. data/CHANGELOG.md +769 -0
  8. data/CONFIG.md +33 -0
  9. data/Dockerfile +41 -0
  10. data/Dockerfile_test +66 -0
  11. data/Gemfile +41 -0
  12. data/LICENSE +193 -0
  13. data/README.md +351 -0
  14. data/Rakefile +202 -0
  15. data/Vagrantfile +67 -0
  16. data/appoptics_apm.gemspec +55 -0
  17. data/build_gems.sh +15 -0
  18. data/docker-compose.yml +73 -0
  19. data/examples/DNT.md +35 -0
  20. data/examples/carrying_context.rb +220 -0
  21. data/examples/instrumenting_metal_controller.rb +8 -0
  22. data/examples/puma_on_heroku_config.rb +17 -0
  23. data/examples/tracing_async_threads.rb +124 -0
  24. data/examples/tracing_background_jobs.rb +53 -0
  25. data/examples/tracing_forked_processes.rb +99 -0
  26. data/examples/unicorn_on_heroku_config.rb +28 -0
  27. data/ext/oboe_metal/extconf.rb +54 -0
  28. data/ext/oboe_metal/lib/.keep +0 -0
  29. data/ext/oboe_metal/lib/liboboe-1.0.so.0.0.0 +0 -0
  30. data/ext/oboe_metal/noop/noop.c +7 -0
  31. data/ext/oboe_metal/src/VERSION +1 -0
  32. data/ext/oboe_metal/src/bson/bson.h +221 -0
  33. data/ext/oboe_metal/src/bson/platform_hacks.h +91 -0
  34. data/ext/oboe_metal/src/oboe.h +883 -0
  35. data/ext/oboe_metal/src/oboe.hpp +793 -0
  36. data/ext/oboe_metal/src/oboe_debug.h +50 -0
  37. data/ext/oboe_metal/src/oboe_wrap.cxx +6088 -0
  38. data/ext/oboe_metal/tests/test.rb +11 -0
  39. data/gemfiles/delayed_job.gemfile +36 -0
  40. data/gemfiles/frameworks.gemfile +44 -0
  41. data/gemfiles/instrumentation_mocked.gemfile +29 -0
  42. data/gemfiles/libraries.gemfile +85 -0
  43. data/gemfiles/rails23.gemfile +39 -0
  44. data/gemfiles/rails30.gemfile +42 -0
  45. data/gemfiles/rails31.gemfile +44 -0
  46. data/gemfiles/rails32.gemfile +54 -0
  47. data/gemfiles/rails40.gemfile +27 -0
  48. data/gemfiles/rails41.gemfile +27 -0
  49. data/gemfiles/rails42.gemfile +35 -0
  50. data/gemfiles/rails50.gemfile +44 -0
  51. data/gemfiles/rails51.gemfile +44 -0
  52. data/get_version.rb +5 -0
  53. data/init.rb +4 -0
  54. data/lib/appoptics_apm/api/layerinit.rb +39 -0
  55. data/lib/appoptics_apm/api/logging.rb +359 -0
  56. data/lib/appoptics_apm/api/memcache.rb +34 -0
  57. data/lib/appoptics_apm/api/profiling.rb +201 -0
  58. data/lib/appoptics_apm/api/tracing.rb +152 -0
  59. data/lib/appoptics_apm/api/util.rb +128 -0
  60. data/lib/appoptics_apm/api.rb +18 -0
  61. data/lib/appoptics_apm/base.rb +252 -0
  62. data/lib/appoptics_apm/config.rb +281 -0
  63. data/lib/appoptics_apm/frameworks/grape.rb +93 -0
  64. data/lib/appoptics_apm/frameworks/padrino/templates.rb +58 -0
  65. data/lib/appoptics_apm/frameworks/padrino.rb +52 -0
  66. data/lib/appoptics_apm/frameworks/rails/inst/action_controller.rb +106 -0
  67. data/lib/appoptics_apm/frameworks/rails/inst/action_controller2.rb +61 -0
  68. data/lib/appoptics_apm/frameworks/rails/inst/action_controller3.rb +58 -0
  69. data/lib/appoptics_apm/frameworks/rails/inst/action_controller4.rb +48 -0
  70. data/lib/appoptics_apm/frameworks/rails/inst/action_controller5.rb +50 -0
  71. data/lib/appoptics_apm/frameworks/rails/inst/action_controller_api.rb +50 -0
  72. data/lib/appoptics_apm/frameworks/rails/inst/action_view.rb +58 -0
  73. data/lib/appoptics_apm/frameworks/rails/inst/action_view_2x.rb +56 -0
  74. data/lib/appoptics_apm/frameworks/rails/inst/action_view_30.rb +50 -0
  75. data/lib/appoptics_apm/frameworks/rails/inst/active_record.rb +27 -0
  76. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/mysql.rb +43 -0
  77. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/mysql2.rb +28 -0
  78. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/postgresql.rb +30 -0
  79. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils.rb +120 -0
  80. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils5x.rb +101 -0
  81. data/lib/appoptics_apm/frameworks/rails.rb +116 -0
  82. data/lib/appoptics_apm/frameworks/sinatra/templates.rb +56 -0
  83. data/lib/appoptics_apm/frameworks/sinatra.rb +71 -0
  84. data/lib/appoptics_apm/inst/bunny-client.rb +148 -0
  85. data/lib/appoptics_apm/inst/bunny-consumer.rb +92 -0
  86. data/lib/appoptics_apm/inst/curb.rb +329 -0
  87. data/lib/appoptics_apm/inst/dalli.rb +85 -0
  88. data/lib/appoptics_apm/inst/delayed_job.rb +92 -0
  89. data/lib/appoptics_apm/inst/em-http-request.rb +105 -0
  90. data/lib/appoptics_apm/inst/excon.rb +130 -0
  91. data/lib/appoptics_apm/inst/faraday.rb +77 -0
  92. data/lib/appoptics_apm/inst/http.rb +83 -0
  93. data/lib/appoptics_apm/inst/httpclient.rb +176 -0
  94. data/lib/appoptics_apm/inst/memcache.rb +102 -0
  95. data/lib/appoptics_apm/inst/memcached.rb +94 -0
  96. data/lib/appoptics_apm/inst/mongo.rb +242 -0
  97. data/lib/appoptics_apm/inst/mongo2.rb +225 -0
  98. data/lib/appoptics_apm/inst/moped.rb +466 -0
  99. data/lib/appoptics_apm/inst/rack.rb +146 -0
  100. data/lib/appoptics_apm/inst/redis.rb +275 -0
  101. data/lib/appoptics_apm/inst/resque.rb +151 -0
  102. data/lib/appoptics_apm/inst/rest-client.rb +50 -0
  103. data/lib/appoptics_apm/inst/sequel.rb +178 -0
  104. data/lib/appoptics_apm/inst/sidekiq-client.rb +53 -0
  105. data/lib/appoptics_apm/inst/sidekiq-worker.rb +67 -0
  106. data/lib/appoptics_apm/inst/twitter-cassandra.rb +294 -0
  107. data/lib/appoptics_apm/inst/typhoeus.rb +113 -0
  108. data/lib/appoptics_apm/instrumentation.rb +22 -0
  109. data/lib/appoptics_apm/legacy_method_profiling.rb +97 -0
  110. data/lib/appoptics_apm/loading.rb +66 -0
  111. data/lib/appoptics_apm/logger.rb +41 -0
  112. data/lib/appoptics_apm/method_profiling.rb +33 -0
  113. data/lib/appoptics_apm/ruby.rb +35 -0
  114. data/lib/appoptics_apm/support.rb +135 -0
  115. data/lib/appoptics_apm/test.rb +94 -0
  116. data/lib/appoptics_apm/thread_local.rb +26 -0
  117. data/lib/appoptics_apm/util.rb +312 -0
  118. data/lib/appoptics_apm/version.rb +15 -0
  119. data/lib/appoptics_apm/xtrace.rb +103 -0
  120. data/lib/appoptics_apm.rb +72 -0
  121. data/lib/joboe_metal.rb +214 -0
  122. data/lib/oboe/README +2 -0
  123. data/lib/oboe/backward_compatibility.rb +80 -0
  124. data/lib/oboe/inst/rack.rb +11 -0
  125. data/lib/oboe.rb +7 -0
  126. data/lib/oboe_metal.rb +187 -0
  127. data/lib/rails/generators/appoptics_apm/install_generator.rb +45 -0
  128. data/lib/rails/generators/appoptics_apm/templates/appoptics_apm_initializer.rb +222 -0
  129. data/ruby_setup.sh +47 -0
  130. data/run_docker_build_gem_upload_to_packagecloud.sh +20 -0
  131. data/run_tests_docker.rb +32 -0
  132. data/test/benchmark/README.md +65 -0
  133. data/test/benchmark/logging_bench.rb +54 -0
  134. data/test/benchmark/with_libraries_gemfile/bunny_bench.rb +69 -0
  135. data/test/benchmark/with_rails5x_gemfile/action_controller5x_bench.rb +43 -0
  136. data/test/frameworks/apps/grape_nested.rb +33 -0
  137. data/test/frameworks/apps/grape_simple.rb +80 -0
  138. data/test/frameworks/apps/padrino_simple.rb +80 -0
  139. data/test/frameworks/apps/sinatra_simple.rb +55 -0
  140. data/test/frameworks/grape_test.rb +286 -0
  141. data/test/frameworks/padrino_test.rb +222 -0
  142. data/test/frameworks/rails3x_test.rb +554 -0
  143. data/test/frameworks/rails4x_test.rb +570 -0
  144. data/test/frameworks/rails5x_api_test.rb +210 -0
  145. data/test/frameworks/rails5x_test.rb +376 -0
  146. data/test/frameworks/rails_shared_tests.rb +172 -0
  147. data/test/frameworks/sinatra_test.rb +140 -0
  148. data/test/instrumentation/bunny_client_test.rb +276 -0
  149. data/test/instrumentation/bunny_consumer_test.rb +204 -0
  150. data/test/instrumentation/curb_test.rb +398 -0
  151. data/test/instrumentation/dalli_test.rb +177 -0
  152. data/test/instrumentation/em_http_request_test.rb +89 -0
  153. data/test/instrumentation/excon_test.rb +231 -0
  154. data/test/instrumentation/faraday_test.rb +228 -0
  155. data/test/instrumentation/http_test.rb +143 -0
  156. data/test/instrumentation/httpclient_test.rb +320 -0
  157. data/test/instrumentation/memcache_test.rb +260 -0
  158. data/test/instrumentation/memcached_test.rb +229 -0
  159. data/test/instrumentation/mongo_v1_test.rb +479 -0
  160. data/test/instrumentation/mongo_v2_index_test.rb +124 -0
  161. data/test/instrumentation/mongo_v2_test.rb +584 -0
  162. data/test/instrumentation/mongo_v2_view_test.rb +435 -0
  163. data/test/instrumentation/moped_test.rb +517 -0
  164. data/test/instrumentation/rack_test.rb +165 -0
  165. data/test/instrumentation/redis_hashes_test.rb +268 -0
  166. data/test/instrumentation/redis_keys_test.rb +321 -0
  167. data/test/instrumentation/redis_lists_test.rb +310 -0
  168. data/test/instrumentation/redis_misc_test.rb +163 -0
  169. data/test/instrumentation/redis_sets_test.rb +296 -0
  170. data/test/instrumentation/redis_sortedsets_test.rb +328 -0
  171. data/test/instrumentation/redis_strings_test.rb +349 -0
  172. data/test/instrumentation/resque_test.rb +185 -0
  173. data/test/instrumentation/rest-client_test.rb +288 -0
  174. data/test/instrumentation/sequel_mysql2_test.rb +353 -0
  175. data/test/instrumentation/sequel_mysql_test.rb +334 -0
  176. data/test/instrumentation/sequel_pg_test.rb +336 -0
  177. data/test/instrumentation/sidekiq-client_test.rb +159 -0
  178. data/test/instrumentation/sidekiq-worker_test.rb +180 -0
  179. data/test/instrumentation/twitter-cassandra_test.rb +424 -0
  180. data/test/instrumentation/typhoeus_test.rb +284 -0
  181. data/test/jobs/delayed_job/db_worker_job.rb +29 -0
  182. data/test/jobs/delayed_job/error_worker_job.rb +10 -0
  183. data/test/jobs/delayed_job/remote_call_worker_job.rb +20 -0
  184. data/test/jobs/resque/db_worker_job.rb +29 -0
  185. data/test/jobs/resque/error_worker_job.rb +10 -0
  186. data/test/jobs/resque/remote_call_worker_job.rb +20 -0
  187. data/test/jobs/sidekiq/db_worker_job.rb +29 -0
  188. data/test/jobs/sidekiq/error_worker_job.rb +10 -0
  189. data/test/jobs/sidekiq/remote_call_worker_job.rb +20 -0
  190. data/test/minitest_helper.rb +276 -0
  191. data/test/mocked/curb_mocked_test.rb +311 -0
  192. data/test/mocked/excon_mocked_test.rb +166 -0
  193. data/test/mocked/faraday_mocked_test.rb +93 -0
  194. data/test/mocked/http_mocked_test.rb +129 -0
  195. data/test/mocked/httpclient_mocked_test.rb +245 -0
  196. data/test/mocked/rest_client_mocked_test.rb +103 -0
  197. data/test/mocked/typhoeus_mocked_test.rb +192 -0
  198. data/test/models/widget.rb +36 -0
  199. data/test/profiling/legacy_method_profiling_test.rb +201 -0
  200. data/test/profiling/method_profiling_test.rb +631 -0
  201. data/test/queues/delayed_job-client_test.rb +95 -0
  202. data/test/queues/delayed_job-worker_test.rb +91 -0
  203. data/test/reporter/reporter_test.rb +14 -0
  204. data/test/servers/delayed_job.rb +107 -0
  205. data/test/servers/rackapp_8101.rb +29 -0
  206. data/test/servers/rails3x_8140.rb +96 -0
  207. data/test/servers/rails4x_8140.rb +96 -0
  208. data/test/servers/rails5x_8140.rb +95 -0
  209. data/test/servers/rails5x_api_8150.rb +78 -0
  210. data/test/servers/sidekiq.rb +29 -0
  211. data/test/servers/sidekiq.yml +7 -0
  212. data/test/servers/sidekiq_initializer.rb +25 -0
  213. data/test/settings +0 -0
  214. data/test/support/auto_tracing_test.rb +50 -0
  215. data/test/support/backcompat_test.rb +276 -0
  216. data/test/support/config_test.rb +149 -0
  217. data/test/support/dnt_test.rb +98 -0
  218. data/test/support/init_report_test.rb +25 -0
  219. data/test/support/liboboe_settings_test.rb +110 -0
  220. data/test/support/logging_test.rb +130 -0
  221. data/test/support/noop_test.rb +88 -0
  222. data/test/support/sql_sanitize_test.rb +55 -0
  223. data/test/support/tracing_mode_test.rb +33 -0
  224. data/test/support/tvalias_test.rb +15 -0
  225. data/test/support/xtrace_test.rb +41 -0
  226. metadata +475 -0
@@ -0,0 +1,584 @@
1
+ # Copyright (c) 2016 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ require 'minitest_helper'
5
+
6
+ ENV['APPOPTICS_MONGO_SERVER'] = "127.0.0.1:27017" unless ENV['APPOPTICS_MONGO_SERVER']
7
+ ENV['APPOPTICS_MONGO_SERVER'] += ":27017" unless ENV['APPOPTICS_MONGO_SERVER'] =~ /\:27017$/
8
+
9
+ if defined?(::Mongo::VERSION) && Mongo::VERSION >= '2.0.0'
10
+ describe "MongoCollection" do
11
+ before do
12
+ clear_all_traces
13
+
14
+ @client = Mongo::Client.new([ ENV['APPOPTICS_MONGO_SERVER'] ], :database => "appoptics_apm-#{ENV['RACK_ENV']}")
15
+ @db = @client.database
16
+
17
+ if Mongo::VERSION < '2.2'
18
+ Mongo::Logger.logger.level = Logger::INFO
19
+ else
20
+ @client.logger.level = Logger::INFO
21
+ end
22
+
23
+ @collections = @db.collection_names
24
+ @testCollection = @client[:test_collection]
25
+ @testCollection.create unless @collections.include? "test_collection"
26
+
27
+ # These are standard entry/exit KVs that are passed up with all mongo operations
28
+ @entry_kvs = {
29
+ 'Layer' => 'mongo',
30
+ 'Label' => 'entry',
31
+ 'Flavor' => 'mongodb',
32
+ 'Database' => 'appoptics_apm-test',
33
+ 'RemoteHost' => ENV['APPOPTICS_MONGO_SERVER'] }
34
+
35
+ @exit_kvs = { 'Layer' => 'mongo', 'Label' => 'exit' }
36
+ @collect_backtraces = AppOpticsAPM::Config[:mongo][:collect_backtraces]
37
+ end
38
+
39
+ after do
40
+ AppOpticsAPM::Config[:mongo][:collect_backtraces] = @collect_backtraces
41
+
42
+ if @db.collection_names.include?("temp_collection")
43
+ @db[:temp_collection].drop
44
+ end
45
+ end
46
+
47
+ it "should trace collection creation" do
48
+ r = nil
49
+ collection = @db[:temp_collection]
50
+ AppOpticsAPM::API.start_trace('mongo_test', nil, {}) do
51
+ r = collection.create
52
+ end
53
+
54
+ traces = get_all_traces
55
+ traces.count.must_equal 4
56
+
57
+ r.must_be_instance_of ::Mongo::Operation::Result
58
+ if Mongo::VERSION < '2.2'
59
+ r.successful?.must_equal true
60
+ else
61
+ r.ok?.must_equal true
62
+ end
63
+
64
+ validate_outer_layers(traces, 'mongo_test')
65
+ validate_event_keys(traces[1], @entry_kvs)
66
+ validate_event_keys(traces[2], @exit_kvs)
67
+
68
+ traces[1]['QueryOp'].must_equal "create"
69
+ traces[1]['New_Collection_Name'].must_equal "temp_collection"
70
+ traces[1].has_key?('Backtrace').must_equal AppOpticsAPM::Config[:mongo][:collect_backtraces]
71
+ end
72
+
73
+ it "should trace drop_collection" do
74
+ r = nil
75
+ collection = @db[:deleteme_collection]
76
+
77
+ # Create something to drop unless it already exists
78
+ unless @db.collection_names.include?("deleteme_collection")
79
+ collection.create
80
+ end
81
+
82
+ AppOpticsAPM::API.start_trace('mongo_test', nil, {}) do
83
+ r = collection.drop
84
+ end
85
+
86
+ traces = get_all_traces
87
+ traces.count.must_equal 4
88
+
89
+ r.must_be_instance_of ::Mongo::Operation::Result
90
+ if Mongo::VERSION < '2.2'
91
+ r.successful?.must_equal true
92
+ else
93
+ r.ok?.must_equal true
94
+ end
95
+
96
+ validate_outer_layers(traces, 'mongo_test')
97
+ validate_event_keys(traces[1], @entry_kvs)
98
+ validate_event_keys(traces[2], @exit_kvs)
99
+
100
+ traces[1]['QueryOp'].must_equal "drop"
101
+ traces[1]['Collection'].must_equal "deleteme_collection"
102
+ traces[1].has_key?('Backtrace').must_equal AppOpticsAPM::Config[:mongo][:collect_backtraces]
103
+ end
104
+
105
+ it "should capture collection creation errors" do
106
+ collection = @db[:temp_collection]
107
+ collection.create
108
+
109
+ begin
110
+ AppOpticsAPM::API.start_trace('mongo_test', nil, {}) do
111
+ collection.create
112
+ end
113
+ rescue
114
+ end
115
+
116
+ traces = get_all_traces
117
+ traces.count.must_equal 5
118
+
119
+ validate_outer_layers(traces, 'mongo_test')
120
+ validate_event_keys(traces[1], @entry_kvs)
121
+ validate_event_keys(traces[3], @exit_kvs)
122
+
123
+ traces[1]['QueryOp'].must_equal "create"
124
+ traces[1]['New_Collection_Name'].must_equal "temp_collection"
125
+ traces[1].has_key?('Backtrace').must_equal AppOpticsAPM::Config[:mongo][:collect_backtraces]
126
+
127
+ traces[2]['Layer'].must_equal "mongo"
128
+ traces[2]['Label'].must_equal "error"
129
+ traces[2]['ErrorClass'].must_equal "Mongo::Error::OperationFailure"
130
+ traces[2]['ErrorMsg'].must_match /collection.*already exists/
131
+ traces[2].has_key?('Backtrace').must_equal true
132
+ end
133
+
134
+ it "should trace insert_one" do
135
+ r = nil
136
+ collection = @db[:tv_collection]
137
+
138
+ AppOpticsAPM::API.start_trace('mongo_test', nil, {}) do
139
+ r = collection.insert_one({ name => 'Rabel Lasen' })
140
+ end
141
+
142
+ traces = get_all_traces
143
+ traces.count.must_equal 4
144
+
145
+ r.must_be_instance_of Mongo::Operation::Write::Insert::Result
146
+ if Mongo::VERSION < '2.2'
147
+ r.successful?.must_equal true
148
+ else
149
+ r.ok?.must_equal true
150
+ end
151
+
152
+ validate_outer_layers(traces, 'mongo_test')
153
+ validate_event_keys(traces[1], @entry_kvs)
154
+ validate_event_keys(traces[2], @exit_kvs)
155
+
156
+ traces[1]['QueryOp'].must_equal "insert_one"
157
+ traces[1]['Collection'].must_equal "tv_collection"
158
+ traces[1].has_key?('Backtrace').must_equal AppOpticsAPM::Config[:mongo][:collect_backtraces]
159
+ end
160
+
161
+ it "should trace insert_many" do
162
+ r = nil
163
+ collection = @db[:tv_collection]
164
+
165
+ AppOpticsAPM::API.start_trace('mongo_test', nil, {}) do
166
+ r = collection.insert_many([
167
+ { :name => 'Rabel Lasen' },
168
+ { :name => 'Louval Raiden' }])
169
+ end
170
+
171
+ traces = get_all_traces
172
+ traces.count.must_equal 4
173
+
174
+ if Mongo::VERSION < '2.1'
175
+ r.must_be_instance_of Mongo::Operation::Write::Insert::Result
176
+ else
177
+ r.must_be_instance_of Mongo::BulkWrite::Result
178
+ r.inserted_count.must_equal 2
179
+ end
180
+
181
+ validate_outer_layers(traces, 'mongo_test')
182
+ validate_event_keys(traces[1], @entry_kvs)
183
+ validate_event_keys(traces[2], @exit_kvs)
184
+
185
+ traces[1]['QueryOp'].must_equal "insert_many"
186
+ traces[1]['Collection'].must_equal "tv_collection"
187
+ traces[1].has_key?('Backtrace').must_equal AppOpticsAPM::Config[:mongo][:collect_backtraces]
188
+ end
189
+
190
+ it "should trace find" do
191
+ coll = @db[:test_collection]
192
+ r = nil
193
+
194
+ # Insert a doc to assure we get a result
195
+ doc = {"name" => "MyName", "type" => "MyType", "count" => 1, "info" => {"x" => 203, "y" => '102'}}
196
+ coll.insert_one(doc)
197
+
198
+ AppOpticsAPM::API.start_trace('mongo_test', '', {}) do
199
+ r = coll.find(:name => "MyName", :limit => 1)
200
+ end
201
+
202
+ traces = get_all_traces
203
+ traces.count.must_equal 4
204
+
205
+ validate_outer_layers(traces, 'mongo_test')
206
+ validate_event_keys(traces[1], @entry_kvs)
207
+ validate_event_keys(traces[2], @exit_kvs)
208
+
209
+ r.must_be_instance_of Mongo::Collection::View
210
+
211
+ traces[1]['Collection'].must_equal "test_collection"
212
+ traces[1].has_key?('Backtrace').must_equal AppOpticsAPM::Config[:mongo][:collect_backtraces]
213
+ traces[1]['QueryOp'].must_equal "find"
214
+ traces[1]['Query'].must_equal "{\"name\":\"MyName\",\"limit\":1}"
215
+ traces[1].has_key?('Query').must_equal true
216
+ end
217
+
218
+ it "should trace find_one_and_delete" do
219
+ skip unless Mongo::VERSION >= '2.1'
220
+
221
+ coll = @db[:test_collection]
222
+ r = nil
223
+
224
+ # Insert a doc to assure we get a result
225
+ doc = {"name" => "MyName", "type" => "MyType", "count" => 1, "info" => {"x" => 203, "y" => '102'}}
226
+ coll.insert_one(doc)
227
+
228
+ AppOpticsAPM::API.start_trace('mongo_test', '', {}) do
229
+ r = coll.find_one_and_delete(:name => "MyName")
230
+ end
231
+
232
+ traces = get_all_traces
233
+ traces.count.must_equal 4
234
+
235
+ validate_outer_layers(traces, 'mongo_test')
236
+ validate_event_keys(traces[1], @entry_kvs)
237
+ validate_event_keys(traces[2], @exit_kvs)
238
+
239
+ r.must_be_instance_of BSON::Document
240
+
241
+ traces[1]['Collection'].must_equal "test_collection"
242
+ traces[1].has_key?('Backtrace').must_equal AppOpticsAPM::Config[:mongo][:collect_backtraces]
243
+ traces[1]['QueryOp'].must_equal "find_one_and_delete"
244
+ traces[1]['Query'].must_equal "{\"name\":\"MyName\"}"
245
+ traces[1].has_key?('Query').must_equal true
246
+ end
247
+
248
+ it "should trace find_one_and_update" do
249
+ skip unless Mongo::VERSION >= '2.1'
250
+ coll = @db[:test_collection]
251
+ r = nil
252
+
253
+ # Insert a doc to assure we get a result
254
+ doc = {"name" => "MyName", "type" => "MyType", "count" => 1, "info" => {"x" => 203, "y" => '102'}}
255
+ coll.insert_one(doc)
256
+
257
+ AppOpticsAPM::API.start_trace('mongo_test', '', {}) do
258
+ r = coll.find_one_and_update({ :name => 'MyName' }, { "$set" => { :name => 'test1' }}, :return_document => :after)
259
+ end
260
+
261
+ traces = get_all_traces
262
+ traces.count.must_equal 4
263
+
264
+ validate_outer_layers(traces, 'mongo_test')
265
+ validate_event_keys(traces[1], @entry_kvs)
266
+ validate_event_keys(traces[2], @exit_kvs)
267
+
268
+ r.must_be_instance_of BSON::Document
269
+
270
+ traces[1]['Collection'].must_equal "test_collection"
271
+ traces[1].has_key?('Backtrace').must_equal AppOpticsAPM::Config[:mongo][:collect_backtraces]
272
+ traces[1]['QueryOp'].must_equal "find_one_and_update"
273
+ traces[1]['Query'].must_equal "{\"name\":\"MyName\"}"
274
+ traces[1].has_key?('Query').must_equal true
275
+ end
276
+
277
+ it "should trace find_one_and_replace" do
278
+ skip unless Mongo::VERSION >= '2.1'
279
+ coll = @db[:test_collection]
280
+ r = nil
281
+
282
+ # Insert a doc to assure we get a result
283
+ doc = {"name" => "MyName", "type" => "MyType", "count" => 1, "info" => {"x" => 203, "y" => '102'}}
284
+ coll.insert_one(doc)
285
+
286
+ AppOpticsAPM::API.start_trace('mongo_test', '', {}) do
287
+ r = coll.find_one_and_replace({ :name => 'MyName' }, { "$set" => { :name => 'test1' }}, :return_document => :after)
288
+ end
289
+
290
+ traces = get_all_traces
291
+ traces.count.must_equal 4
292
+
293
+ validate_outer_layers(traces, 'mongo_test')
294
+ validate_event_keys(traces[1], @entry_kvs)
295
+ validate_event_keys(traces[2], @exit_kvs)
296
+
297
+ r.must_be_instance_of BSON::Document
298
+
299
+ traces[1]['Collection'].must_equal "test_collection"
300
+ traces[1].has_key?('Backtrace').must_equal AppOpticsAPM::Config[:mongo][:collect_backtraces]
301
+ traces[1]['QueryOp'].must_equal "find_one_and_replace"
302
+ traces[1]['Query'].must_equal "{\"name\":\"MyName\"}"
303
+ traces[1].has_key?('Query').must_equal true
304
+ end
305
+
306
+ it "should trace update_one" do
307
+ skip unless Mongo::VERSION >= '2.1'
308
+
309
+ coll = @db[:test_collection]
310
+ r = nil
311
+
312
+ # Insert a doc to assure we get a result
313
+ doc = {"name" => "MyName", "type" => "MyType", "count" => 1, "info" => {"x" => 203, "y" => '102'}}
314
+ coll.insert_one(doc)
315
+
316
+ AppOpticsAPM::API.start_trace('mongo_test', '', {}) do
317
+ r = coll.update_one({ :name => 'MyName' }, { "$set" => { :name => 'test1' }}, :return_document => :after)
318
+ end
319
+
320
+ traces = get_all_traces
321
+ traces.count.must_equal 4
322
+
323
+ validate_outer_layers(traces, 'mongo_test')
324
+ validate_event_keys(traces[1], @entry_kvs)
325
+ validate_event_keys(traces[2], @exit_kvs)
326
+
327
+ r.class.ancestors.include?(Mongo::Operation::Result).must_equal true
328
+
329
+ traces[1]['Collection'].must_equal "test_collection"
330
+ traces[1].has_key?('Backtrace').must_equal AppOpticsAPM::Config[:mongo][:collect_backtraces]
331
+ traces[1]['QueryOp'].must_equal "update_one"
332
+ traces[1]['Query'].must_equal "{\"name\":\"MyName\"}"
333
+ traces[1].has_key?('Query').must_equal true
334
+ end
335
+
336
+ it "should trace update_many" do
337
+ skip unless Mongo::VERSION > '2.1'
338
+ coll = @db[:test_collection]
339
+ r = nil
340
+
341
+ # Insert a doc to assure we get a result
342
+ doc = {"name" => "MyName", "type" => "MyType", "count" => 1, "info" => {"x" => 203, "y" => '102'}}
343
+ coll.insert_one(doc)
344
+
345
+ AppOpticsAPM::API.start_trace('mongo_test', '', {}) do
346
+ r = coll.update_many({ :name => 'MyName' }, { "$set" => { :name => 'test1' }}, :return_document => :after)
347
+ end
348
+
349
+ traces = get_all_traces
350
+ traces.count.must_equal 4
351
+
352
+ validate_outer_layers(traces, 'mongo_test')
353
+ validate_event_keys(traces[1], @entry_kvs)
354
+ validate_event_keys(traces[2], @exit_kvs)
355
+
356
+ r.class.ancestors.include?(Mongo::Operation::Result).must_equal true
357
+
358
+ traces[1]['Collection'].must_equal "test_collection"
359
+ traces[1].has_key?('Backtrace').must_equal AppOpticsAPM::Config[:mongo][:collect_backtraces]
360
+ traces[1]['QueryOp'].must_equal "update_many"
361
+ traces[1]['Query'].must_equal "{\"name\":\"MyName\"}"
362
+ traces[1].has_key?('Query').must_equal true
363
+ end
364
+
365
+ it "should trace delete_one" do
366
+ skip unless Mongo::VERSION > '2.1'
367
+ coll = @db[:test_collection]
368
+ r = nil
369
+
370
+ # Insert a doc to assure we get a result
371
+ doc = {"name" => "MyName", "type" => "MyType", "count" => 1, "info" => {"x" => 203, "y" => '102'}}
372
+ coll.insert_one(doc)
373
+
374
+ AppOpticsAPM::API.start_trace('mongo_test', '', {}) do
375
+ r = coll.delete_one({ :name => 'MyName' })
376
+ end
377
+
378
+ traces = get_all_traces
379
+ traces.count.must_equal 4
380
+
381
+ validate_outer_layers(traces, 'mongo_test')
382
+ validate_event_keys(traces[1], @entry_kvs)
383
+ validate_event_keys(traces[2], @exit_kvs)
384
+
385
+ r.class.ancestors.include?(Mongo::Operation::Result).must_equal true
386
+
387
+ traces[1]['Collection'].must_equal "test_collection"
388
+ traces[1].has_key?('Backtrace').must_equal AppOpticsAPM::Config[:mongo][:collect_backtraces]
389
+ traces[1]['QueryOp'].must_equal "delete_one"
390
+ traces[1]['Query'].must_equal "{\"name\":\"MyName\"}"
391
+ traces[1].has_key?('Query').must_equal true
392
+ end
393
+
394
+ it "should trace delete_many" do
395
+ skip unless Mongo::VERSION > '2.1'
396
+ coll = @db[:test_collection]
397
+ r = nil
398
+
399
+ # Insert a doc to assure we get a result
400
+ doc = {"name" => "MyName", "type" => "MyType", "count" => 1, "info" => {"x" => 203, "y" => '102'}}
401
+ coll.insert_one(doc)
402
+
403
+ AppOpticsAPM::API.start_trace('mongo_test', '', {}) do
404
+ r = coll.delete_many({ :name => 'MyName' })
405
+ end
406
+
407
+ traces = get_all_traces
408
+ traces.count.must_equal 4
409
+
410
+ validate_outer_layers(traces, 'mongo_test')
411
+ validate_event_keys(traces[1], @entry_kvs)
412
+ validate_event_keys(traces[2], @exit_kvs)
413
+
414
+ r.class.ancestors.include?(Mongo::Operation::Result).must_equal true
415
+
416
+ traces[1]['Collection'].must_equal "test_collection"
417
+ traces[1].has_key?('Backtrace').must_equal AppOpticsAPM::Config[:mongo][:collect_backtraces]
418
+ traces[1]['QueryOp'].must_equal "delete_many"
419
+ traces[1]['Query'].must_equal "{\"name\":\"MyName\"}"
420
+ traces[1].has_key?('Query').must_equal true
421
+ end
422
+
423
+ it "should trace replace_one" do
424
+ skip unless Mongo::VERSION > '2.1'
425
+ coll = @db[:test_collection]
426
+ r = nil
427
+
428
+ # Insert a doc to assure we get a result
429
+ doc = {"name" => "MyName", "type" => "MyType", "count" => 1, "info" => {"x" => 203, "y" => '102'}}
430
+ coll.insert_one(doc)
431
+
432
+ AppOpticsAPM::API.start_trace('mongo_test', '', {}) do
433
+ r = coll.replace_one({ :name => 'test' }, { :name => 'test1' })
434
+ end
435
+
436
+ traces = get_all_traces
437
+ traces.count.must_equal 4
438
+
439
+ validate_outer_layers(traces, 'mongo_test')
440
+ validate_event_keys(traces[1], @entry_kvs)
441
+ validate_event_keys(traces[2], @exit_kvs)
442
+
443
+ r.class.ancestors.include?(Mongo::Operation::Result).must_equal true
444
+
445
+ traces[1]['Collection'].must_equal "test_collection"
446
+ traces[1].has_key?('Backtrace').must_equal AppOpticsAPM::Config[:mongo][:collect_backtraces]
447
+ traces[1]['QueryOp'].must_equal "replace_one"
448
+ traces[1]['Query'].must_equal "{\"name\":\"test\"}"
449
+ traces[1].has_key?('Query').must_equal true
450
+ end
451
+
452
+ it "should trace count" do
453
+ skip unless Mongo::VERSION > '2.1'
454
+ coll = @db[:test_collection]
455
+ r = nil
456
+
457
+ AppOpticsAPM::API.start_trace('mongo_test', '', {}) do
458
+ r = coll.count({ :name => 'MyName' })
459
+ end
460
+
461
+ traces = get_all_traces
462
+ traces.count.must_equal 4
463
+
464
+ validate_outer_layers(traces, 'mongo_test')
465
+ validate_event_keys(traces[1], @entry_kvs)
466
+ validate_event_keys(traces[2], @exit_kvs)
467
+
468
+ r.is_a?(Numeric).must_equal true
469
+
470
+ traces[1]['Collection'].must_equal "test_collection"
471
+ traces[1].has_key?('Backtrace').must_equal AppOpticsAPM::Config[:mongo][:collect_backtraces]
472
+ traces[1]['QueryOp'].must_equal "count"
473
+ traces[1]['Query'].must_equal "{\"name\":\"MyName\"}"
474
+ traces[1].has_key?('Query').must_equal true
475
+ end
476
+
477
+ it "should trace distinct" do
478
+ skip unless Mongo::VERSION > '2.1'
479
+ coll = @db[:test_collection]
480
+ r = nil
481
+
482
+ AppOpticsAPM::API.start_trace('mongo_test', '', {}) do
483
+ r = coll.distinct('name', { :name => 'MyName' })
484
+ end
485
+
486
+ traces = get_all_traces
487
+ traces.count.must_equal 4
488
+
489
+ validate_outer_layers(traces, 'mongo_test')
490
+ validate_event_keys(traces[1], @entry_kvs)
491
+ validate_event_keys(traces[2], @exit_kvs)
492
+
493
+ r.is_a?(Array).must_equal true
494
+
495
+ traces[1]['Collection'].must_equal "test_collection"
496
+ traces[1].has_key?('Backtrace').must_equal AppOpticsAPM::Config[:mongo][:collect_backtraces]
497
+ traces[1]['QueryOp'].must_equal "distinct"
498
+ traces[1]['Query'].must_equal "{\"name\":\"MyName\"}"
499
+ traces[1].has_key?('Query').must_equal true
500
+ end
501
+
502
+ it "should trace aggregate" do
503
+ skip unless Mongo::VERSION >= '2.1'
504
+ coll = @db[:test_collection]
505
+ r = nil
506
+
507
+ AppOpticsAPM::API.start_trace('mongo_test', '', {}) do
508
+ r = coll.aggregate([ { "$group" => { "_id" => "$city", "tpop" => { "$sum" => "$pop" }}} ])
509
+ end
510
+
511
+ traces = get_all_traces
512
+ traces.count.must_equal 4
513
+
514
+ validate_outer_layers(traces, 'mongo_test')
515
+ validate_event_keys(traces[1], @entry_kvs)
516
+ validate_event_keys(traces[2], @exit_kvs)
517
+
518
+ r.must_be_instance_of Mongo::Collection::View::Aggregation
519
+
520
+ traces[1]['Collection'].must_equal "test_collection"
521
+ traces[1].has_key?('Backtrace').must_equal AppOpticsAPM::Config[:mongo][:collect_backtraces]
522
+ traces[1]['QueryOp'].must_equal "aggregate"
523
+ traces[1].key?('Query').must_equal false
524
+ end
525
+
526
+ it "should trace bulk_write" do
527
+ coll = @db[:test_collection]
528
+ r = nil
529
+
530
+ AppOpticsAPM::API.start_trace('mongo_test', '', {}) do
531
+ r = coll.bulk_write([ { :insert_one => { :x => 1} },
532
+ { :insert_one => { :x => 3} } ],
533
+ :ordered => true)
534
+ end
535
+
536
+ traces = get_all_traces
537
+ traces.count.must_equal 4
538
+
539
+ validate_outer_layers(traces, 'mongo_test')
540
+ validate_event_keys(traces[1], @entry_kvs)
541
+ validate_event_keys(traces[2], @exit_kvs)
542
+
543
+ if Mongo::VERSION < '2.1'
544
+ r.must_be_instance_of Hash
545
+ r[:n_inserted].must_equal 2
546
+ else
547
+ r.must_be_instance_of Mongo::BulkWrite::Result
548
+ end
549
+
550
+ traces[1]['Collection'].must_equal "test_collection"
551
+ traces[1].has_key?('Backtrace').must_equal AppOpticsAPM::Config[:mongo][:collect_backtraces]
552
+ traces[1]['QueryOp'].must_equal "bulk_write"
553
+ traces[1].key?('Query').must_equal false
554
+ end
555
+
556
+ it "should obey :collect_backtraces setting when true" do
557
+ AppOpticsAPM::Config[:mongo][:collect_backtraces] = true
558
+
559
+ coll = @db[:test_collection]
560
+
561
+ AppOpticsAPM::API.start_trace('mongo_test', '', {}) do
562
+ doc = {"name" => "MyName", "type" => "MyType", "count" => 1, "info" => {"x" => 203, "y" => '102'}}
563
+ coll.insert_one(doc)
564
+ end
565
+
566
+ traces = get_all_traces
567
+ layer_has_key(traces, 'mongo', 'Backtrace')
568
+ end
569
+
570
+ it "should obey :collect_backtraces setting when false" do
571
+ AppOpticsAPM::Config[:mongo][:collect_backtraces] = false
572
+
573
+ coll = @db[:test_collection]
574
+
575
+ AppOpticsAPM::API.start_trace('mongo_test', '', {}) do
576
+ doc = {"name" => "MyName", "type" => "MyType", "count" => 1, "info" => {"x" => 203, "y" => '102'}}
577
+ coll.insert_one(doc)
578
+ end
579
+
580
+ traces = get_all_traces
581
+ layer_doesnt_have_key(traces, 'mongo', 'Backtrace')
582
+ end
583
+ end
584
+ end