require 'minitest_helper' if RUBY_VERSION >= '1.9.3' # Moped is tested against MRI 1.9.3, 2.0.0, and JRuby (1.9). describe Oboe::Inst::Moped do before do clear_all_traces @session = Moped::Session.new([ "127.0.0.1:27017" ]) @session.use :moped_test @users = @session[:users] @users.insert({ :name => "Syd", :city => "Boston" }) # These are standard entry/exit KVs that are passed up with all moped operations @entry_kvs = { 'Layer' => 'mongo', 'Label' => 'entry', 'Flavor' => 'mongodb', 'Database' => 'moped_test', 'RemoteHost' => '127.0.0.1', 'RemotePort' => '27017' } @exit_kvs = { 'Layer' => 'mongo', 'Label' => 'exit' } @collect_backtraces = Oboe::Config[:moped][:collect_backtraces] end after do Oboe::Config[:moped][:collect_backtraces] = @collect_backtraces end it 'Stock Moped should be loaded, defined and ready' do defined?(::Moped).wont_match nil defined?(::Moped::Database).wont_match nil defined?(::Moped::Indexes).wont_match nil defined?(::Moped::Query).wont_match nil defined?(::Moped::Collection).wont_match nil end it 'Moped should have oboe methods defined' do #::Moped::Database Oboe::Inst::Moped::DB_OPS.each do |m| ::Moped::Database.method_defined?("#{m}_with_oboe").must_equal true end ::Moped::Database.method_defined?(:extract_trace_details).must_equal true ::Moped::Database.method_defined?(:command_with_oboe).must_equal true ::Moped::Database.method_defined?(:drop_with_oboe).must_equal true #::Moped::Indexes Oboe::Inst::Moped::INDEX_OPS.each do |m| ::Moped::Indexes.method_defined?("#{m}_with_oboe").must_equal true end ::Moped::Indexes.method_defined?(:extract_trace_details).must_equal true ::Moped::Indexes.method_defined?(:create_with_oboe).must_equal true ::Moped::Indexes.method_defined?(:drop_with_oboe).must_equal true #::Moped::Query Oboe::Inst::Moped::QUERY_OPS.each do |m| ::Moped::Query.method_defined?("#{m}_with_oboe").must_equal true end ::Moped::Query.method_defined?(:extract_trace_details).must_equal true #::Moped::Collection Oboe::Inst::Moped::COLLECTION_OPS.each do |m| ::Moped::Collection.method_defined?("#{m}_with_oboe").must_equal true end ::Moped::Collection.method_defined?(:extract_trace_details).must_equal true end it 'should trace command' do # TODO: This randomly fails for a yet unknown reason. skip Oboe::API.start_trace('moped_test', '', {}) do command = {} command[:mapreduce] = "users" command[:map] = "function() { emit(this.name, 1); }" command[:reduce] = "function(k, vals) { var sum = 0;" + " for(var i in vals) sum += vals[i]; return sum; }" command[:out] = "inline: 1" @session.command(command) end traces = get_all_traces traces.count.must_equal 4 validate_outer_layers(traces, 'moped_test') validate_event_keys(traces[1], @entry_kvs) traces[1]['QueryOp'].must_equal "map_reduce" traces[1]['Map_Function'].must_equal "function() { emit(this.name, 1); }" traces[1]['Reduce_Function'].must_equal "function(k, vals) { var sum = 0;" + " for(var i in vals) sum += vals[i]; return sum; }" traces[1].has_key?('Backtrace').must_equal Oboe::Config[:moped][:collect_backtraces] validate_event_keys(traces[2], @exit_kvs) end it 'should trace drop_collection' do Oboe::API.start_trace('moped_test', '', {}) do @users.drop @session.drop end traces = get_all_traces traces.count.must_equal 6 validate_outer_layers(traces, 'moped_test') validate_event_keys(traces[1], @entry_kvs) traces[1]['QueryOp'].must_equal "drop_collection" traces[1]['Collection'].must_equal "users" traces[1].has_key?('Backtrace').must_equal Oboe::Config[:moped][:collect_backtraces] validate_event_keys(traces[2], @exit_kvs) validate_event_keys(traces[3], @entry_kvs) traces[3]['QueryOp'].must_equal "drop_database" traces[3].has_key?('Backtrace').must_equal Oboe::Config[:moped][:collect_backtraces] validate_event_keys(traces[4], @exit_kvs) end it 'should trace create_index, indexes and drop_indexes' do Oboe::API.start_trace('moped_test', '', {}) do @users.indexes.create({:name => 1}, {:unique => true}) @users.indexes.drop end traces = get_all_traces traces.count.must_equal 10 validate_outer_layers(traces, 'moped_test') validate_event_keys(traces[1], @entry_kvs) traces[1]['QueryOp'].must_equal "indexes" traces[1]['Collection'].must_equal "users" traces[1].has_key?('Backtrace').must_equal Oboe::Config[:moped][:collect_backtraces] validate_event_keys(traces[2], @exit_kvs) validate_event_keys(traces[3], @entry_kvs) traces[3]['QueryOp'].must_equal "create_index" traces[3]['Key'].must_equal "{\"name\":1}" traces[3]['Options'].must_equal "{\"unique\":true}" traces[3].has_key?('Backtrace').must_equal Oboe::Config[:moped][:collect_backtraces] validate_event_keys(traces[4], @exit_kvs) validate_event_keys(traces[5], @entry_kvs) traces[5]['QueryOp'].must_equal "indexes" traces[5]['Collection'].must_equal "users" traces[5].has_key?('Backtrace').must_equal Oboe::Config[:moped][:collect_backtraces] validate_event_keys(traces[6], @exit_kvs) validate_event_keys(traces[7], @entry_kvs) traces[7]['QueryOp'].must_equal "drop_indexes" traces[7]['Key'].must_equal "all" traces[7].has_key?('Backtrace').must_equal Oboe::Config[:moped][:collect_backtraces] validate_event_keys(traces[8], @exit_kvs) end it 'should trace find and count' do Oboe::API.start_trace('moped_test', '', {}) do @users.find.count end traces = get_all_traces traces.count.must_equal 6 validate_outer_layers(traces, 'moped_test') validate_event_keys(traces[1], @entry_kvs) traces[1]['QueryOp'].must_equal "find" traces[1]['Collection'].must_equal "users" traces[1].has_key?('Backtrace').must_equal Oboe::Config[:moped][:collect_backtraces] validate_event_keys(traces[2], @exit_kvs) validate_event_keys(traces[3], @entry_kvs) traces[3]['QueryOp'].must_equal "count" traces[3]['Query'].must_equal "all" traces[3].has_key?('Backtrace').must_equal Oboe::Config[:moped][:collect_backtraces] validate_event_keys(traces[4], @exit_kvs) end it 'should trace find and sort' do Oboe::API.start_trace('moped_test', '', {}) do @users.find(:name => "Mary").sort(:city => 1, :created_at => -1) end traces = get_all_traces traces.count.must_equal 6 validate_outer_layers(traces, 'moped_test') validate_event_keys(traces[1], @entry_kvs) traces[1]['QueryOp'].must_equal "find" traces[1]['Query'].must_equal "{\"name\":\"Mary\"}" traces[1]['Collection'].must_equal "users" traces[1].has_key?('Backtrace').must_equal Oboe::Config[:moped][:collect_backtraces] validate_event_keys(traces[2], @exit_kvs) validate_event_keys(traces[3], @entry_kvs) traces[3]['QueryOp'].must_equal "sort" traces[3]['Query'].must_equal "{\"name\":\"Mary\"}" traces[3]['Order'].must_equal "{:city=>1, :created_at=>-1}" traces[3].has_key?('Backtrace').must_equal Oboe::Config[:moped][:collect_backtraces] validate_event_keys(traces[4], @exit_kvs) end it 'should trace find with limit' do Oboe::API.start_trace('moped_test', '', {}) do @users.find(:name => "Mary").limit(1) end traces = get_all_traces traces.count.must_equal 6 validate_outer_layers(traces, 'moped_test') validate_event_keys(traces[1], @entry_kvs) traces[1]['QueryOp'].must_equal "find" traces[1]['Query'].must_equal "{\"name\":\"Mary\"}" traces[1]['Collection'].must_equal "users" traces[1].has_key?('Backtrace').must_equal Oboe::Config[:moped][:collect_backtraces] validate_event_keys(traces[2], @exit_kvs) validate_event_keys(traces[3], @entry_kvs) traces[3]['QueryOp'].must_equal "limit" traces[3]['Query'].must_equal "{\"name\":\"Mary\"}" traces[3]['Limit'].must_equal "1" traces[3].has_key?('Backtrace').must_equal Oboe::Config[:moped][:collect_backtraces] validate_event_keys(traces[4], @exit_kvs) end it 'should trace find with distinct' do Oboe::API.start_trace('moped_test', '', {}) do @users.find(:name => "Mary").distinct(:city) end traces = get_all_traces traces.count.must_equal 6 validate_outer_layers(traces, 'moped_test') validate_event_keys(traces[1], @entry_kvs) traces[1]['QueryOp'].must_equal "find" traces[1]['Query'].must_equal "{\"name\":\"Mary\"}" traces[1]['Collection'].must_equal "users" traces[1].has_key?('Backtrace').must_equal Oboe::Config[:moped][:collect_backtraces] validate_event_keys(traces[2], @exit_kvs) validate_event_keys(traces[3], @entry_kvs) traces[3]['QueryOp'].must_equal "distinct" traces[3]['Query'].must_equal "{\"name\":\"Mary\"}" traces[3]['Key'].must_equal "city" traces[3].has_key?('Backtrace').must_equal Oboe::Config[:moped][:collect_backtraces] validate_event_keys(traces[4], @exit_kvs) end it 'should trace find and update' do Oboe::API.start_trace('moped_test', '', {}) do @users.find(:name => "Mary").update({:name => "Tool"}, [:multi]) end traces = get_all_traces traces.count.must_equal 6 validate_outer_layers(traces, 'moped_test') validate_event_keys(traces[1], @entry_kvs) traces[1]['QueryOp'].must_equal "find" traces[1]['Query'].must_equal "{\"name\":\"Mary\"}" traces[1]['Collection'].must_equal "users" traces[1].has_key?('Backtrace').must_equal Oboe::Config[:moped][:collect_backtraces] validate_event_keys(traces[2], @exit_kvs) validate_event_keys(traces[3], @entry_kvs) traces[3]['QueryOp'].must_equal "update" traces[3]['Update_Document'].must_equal "{\"name\":\"Tool\"}" traces[3]['Flags'].must_equal "[:multi]" traces[3]['Collection'].must_equal "users" traces[3].has_key?('Backtrace').must_equal Oboe::Config[:moped][:collect_backtraces] validate_event_keys(traces[4], @exit_kvs) end it 'should trace find and update_all' do Oboe::API.start_trace('moped_test', '', {}) do @users.find(:name => "Mary").update_all({:name => "Tool"}) end traces = get_all_traces traces.count.must_equal 6 validate_outer_layers(traces, 'moped_test') validate_event_keys(traces[1], @entry_kvs) traces[1]['QueryOp'].must_equal "find" traces[1]['Query'].must_equal "{\"name\":\"Mary\"}" traces[1]['Collection'].must_equal "users" traces[1].has_key?('Backtrace').must_equal Oboe::Config[:moped][:collect_backtraces] validate_event_keys(traces[2], @exit_kvs) validate_event_keys(traces[3], @entry_kvs) traces[3]['QueryOp'].must_equal "update_all" traces[3]['Update_Document'].must_equal "{\"name\":\"Tool\"}" traces[3]['Collection'].must_equal "users" traces[3].has_key?('Backtrace').must_equal Oboe::Config[:moped][:collect_backtraces] validate_event_keys(traces[4], @exit_kvs) end it 'should trace find and upsert' do Oboe::API.start_trace('moped_test', '', {}) do @users.find(:name => "Tool").upsert({:name => "Mary"}) end traces = get_all_traces traces.count.must_equal 6 validate_outer_layers(traces, 'moped_test') validate_event_keys(traces[1], @entry_kvs) traces[1]['QueryOp'].must_equal "find" traces[1]['Query'].must_equal "{\"name\":\"Tool\"}" traces[1]['Collection'].must_equal "users" traces[1].has_key?('Backtrace').must_equal Oboe::Config[:moped][:collect_backtraces] validate_event_keys(traces[2], @exit_kvs) validate_event_keys(traces[3], @entry_kvs) traces[3]['QueryOp'].must_equal "upsert" traces[3]['Query'].must_equal "{\"name\":\"Tool\"}" traces[3]['Update_Document'].must_equal "{\"name\":\"Mary\"}" traces[3]['Collection'].must_equal "users" traces[3].has_key?('Backtrace').must_equal Oboe::Config[:moped][:collect_backtraces] validate_event_keys(traces[4], @exit_kvs) end it 'should trace find and explain' do Oboe::API.start_trace('moped_test', '', {}) do @users.find(:name => "Mary").explain end traces = get_all_traces traces.count.must_equal 6 validate_outer_layers(traces, 'moped_test') validate_event_keys(traces[1], @entry_kvs) traces[1]['QueryOp'].must_equal "find" traces[1]['Query'].must_equal "{\"name\":\"Mary\"}" traces[1]['Collection'].must_equal "users" traces[1].has_key?('Backtrace').must_equal Oboe::Config[:moped][:collect_backtraces] validate_event_keys(traces[2], @exit_kvs) validate_event_keys(traces[3], @entry_kvs) traces[3]['QueryOp'].must_equal "explain" traces[3]['Query'].must_equal "{\"name\":\"Mary\"}" traces[3]['Collection'].must_equal "users" traces[3].has_key?('Backtrace').must_equal Oboe::Config[:moped][:collect_backtraces] validate_event_keys(traces[4], @exit_kvs) end it 'should trace 3 types of find and modify calls' do Oboe::API.start_trace('moped_test', '', {}) do @users.find(:likes => 1).modify({ "$set" => { :name => "Tool" }}, :upsert => true) @users.find.modify({:query => { "$inc" => { :likes => 1 }}}, :new => true) @users.find.modify({:query => {}}, :remove => true) end traces = get_all_traces traces.count.must_equal 14 validate_outer_layers(traces, 'moped_test') validate_event_keys(traces[1], @entry_kvs) traces[1]['QueryOp'].must_equal "find" traces[1]['Query'].must_equal "{\"likes\":1}" traces[1]['Collection'].must_equal "users" traces[1].has_key?('Backtrace').must_equal Oboe::Config[:moped][:collect_backtraces] validate_event_keys(traces[2], @exit_kvs) validate_event_keys(traces[3], @entry_kvs) traces[3]['QueryOp'].must_equal "modify" traces[3]['Update_Document'].must_equal "{\"likes\":1}" traces[3]['Collection'].must_equal "users" traces[3]['Options'].must_equal "{\"upsert\":true}" traces[3].has_key?('Backtrace').must_equal Oboe::Config[:moped][:collect_backtraces] validate_event_keys(traces[4], @exit_kvs) validate_event_keys(traces[7], @entry_kvs) traces[7]['QueryOp'].must_equal "modify" traces[7]['Update_Document'].must_equal "all" traces[7]['Collection'].must_equal "users" traces[7]['Options'].must_equal "{\"new\":true}" traces[7]['Change'].must_equal "{\"query\":{\"$inc\":{\"likes\":1}}}" traces[7].has_key?('Backtrace').must_equal Oboe::Config[:moped][:collect_backtraces] validate_event_keys(traces[8], @exit_kvs) validate_event_keys(traces[11], @entry_kvs) traces[11]['Collection'].must_equal "users" traces[11]['QueryOp'].must_equal "modify" traces[11]['Update_Document'].must_equal "all" traces[11]['Change'].must_equal "{\"query\":{}}" traces[11]['Options'].must_equal "{\"remove\":true}" traces[11].has_key?('Backtrace').must_equal Oboe::Config[:moped][:collect_backtraces] validate_event_keys(traces[12], @exit_kvs) end it 'should trace remove' do Oboe::API.start_trace('moped_test', '', {}) do @users.find(:name => "Tool").remove end traces = get_all_traces traces.count.must_equal 6 validate_outer_layers(traces, 'moped_test') validate_event_keys(traces[1], @entry_kvs) traces[1]['QueryOp'].must_equal "find" traces[1]['Query'].must_equal "{\"name\":\"Tool\"}" traces[1]['Collection'].must_equal "users" traces[1].has_key?('Backtrace').must_equal Oboe::Config[:moped][:collect_backtraces] validate_event_keys(traces[2], @exit_kvs) validate_event_keys(traces[3], @entry_kvs) traces[3]['QueryOp'].must_equal "remove" traces[3]['Query'].must_equal "{\"name\":\"Tool\"}" traces[3]['Collection'].must_equal "users" traces[3].has_key?('Backtrace').must_equal Oboe::Config[:moped][:collect_backtraces] validate_event_keys(traces[4], @exit_kvs) end it 'should trace remove_all' do Oboe::API.start_trace('moped_test', '', {}) do @users.find(:name => "Mary").remove_all end traces = get_all_traces traces.count.must_equal 6 validate_outer_layers(traces, 'moped_test') validate_event_keys(traces[1], @entry_kvs) traces[1]['QueryOp'].must_equal "find" traces[1]['Query'].must_equal "{\"name\":\"Mary\"}" traces[1]['Collection'].must_equal "users" traces[1].has_key?('Backtrace').must_equal Oboe::Config[:moped][:collect_backtraces] validate_event_keys(traces[2], @exit_kvs) validate_event_keys(traces[3], @entry_kvs) traces[3]['QueryOp'].must_equal "remove_all" traces[3]['Query'].must_equal "{\"name\":\"Mary\"}" traces[3]['Collection'].must_equal "users" traces[3].has_key?('Backtrace').must_equal Oboe::Config[:moped][:collect_backtraces] validate_event_keys(traces[4], @exit_kvs) end it "should obey :collect_backtraces setting when true" do Oboe::Config[:moped][:collect_backtraces] = true Oboe::API.start_trace('moped_test', '', {}) do @users.find(:name => "Mary").limit(1) end traces = get_all_traces layer_has_key(traces, 'mongo', 'Backtrace') end it "should obey :collect_backtraces setting when false" do Oboe::Config[:moped][:collect_backtraces] = false Oboe::API.start_trace('moped_test', '', {}) do @users.find(:name => "Mary").limit(1) end traces = get_all_traces layer_doesnt_have_key(traces, 'mongo', 'Backtrace') end end end