spec/elastic_apm/spies/mongo_spec.rb (103 lines of code) (raw):
# Licensed to Elasticsearch B.V. under one or more contributor
# license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright
# ownership. Elasticsearch B.V. licenses this file to you under
# the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# frozen_string_literal: true
require 'spec_helper'
require 'mongo'
module ElasticAPM
RSpec.describe 'Spy: MongoDB' do
context 'db admin commands' do
let(:event) do
double('event',
command: { 'listCollections' => 1 },
command_name: 'listCollections',
database_name: 'elastic-apm-test',
operation_id: 123)
end
let(:subscriber) { Spies::MongoSpy::Subscriber.new }
it 'captures command properties', :intercept do
span = with_agent do
ElasticAPM.with_transaction do
subscriber.started(event)
subscriber.succeeded(event)
end
end
expect(span.name).to eq 'elastic-apm-test.listCollections'
expect(span.type).to eq 'db'
expect(span.subtype).to eq 'mongodb'
expect(span.action).to eq 'query'
expect(span.duration).to_not be_nil
expect(span.outcome).to eq 'success'
db = span.context.db
expect(db.instance).to eq 'elastic-apm-test'
expect(db.type).to eq 'mongodb'
expect(db.statement).to eq('{"listCollections"=>1}')
.or eq("{\"listCollections\" => 1}")
expect(db.user).to be nil
destination = span.context.destination
expect(destination.service.name).to eq 'mongodb'
expect(destination.service.resource).to eq 'mongodb'
expect(destination.service.type).to eq 'db'
end
it 'sets outcome to `failure` for a failed operation', :intercept do
span = with_agent do
ElasticAPM.with_transaction do
subscriber.started(event)
subscriber.failed(event)
end
end
expect(span.outcome).to eq 'failure'
end
end
context 'collection commands', :intercept do
let(:event) do
double('event',
command: { 'find' => 'testing',
'filter' => { 'a' => 'bc' } },
command_name: 'find',
database_name: 'elastic-apm-test',
operation_id: 456)
end
let(:subscriber) { Spies::MongoSpy::Subscriber.new }
it 'captures command properties' do
span = with_agent do
ElasticAPM.with_transaction do
subscriber.started(event)
subscriber.succeeded(event)
end
end
expect(span.name).to eq 'elastic-apm-test.testing.find'
expect(span.type).to eq 'db'
expect(span.subtype).to eq 'mongodb'
expect(span.action).to eq 'query'
expect(span.duration).to_not be_nil
expect(span.outcome).to eq 'success'
db = span.context.db
expect(db.instance).to eq 'elastic-apm-test'
expect(db.type).to eq 'mongodb'
expect(db.statement).to eq('{"find"=>"testing", "filter"=>{"a"=>"bc"}}')
.or eq("{\"find\" => \"testing\", \"filter\" => {\"a\" => \"bc\"}}")
expect(db.user).to be nil
end
end
context 'requests in different threads', :intercept do
let(:subscriber) { Spies::MongoSpy::Subscriber.new }
it 'captures all operations' do
thread_count = 50
with_agent do
Array.new(thread_count).map do
Thread.new do |t|
event = double('event',
command: { 'find' => 'testing',
'filter' => { 'a' => 'bc' } },
command_name: 'find',
database_name: 'elastic-apm-test',
operation_id: rand(thread_count+1))
ElasticAPM.with_transaction do
subscriber.started(event)
subscriber.succeeded(event)
end
end
end.map(&:join)
end
expect(@intercepted.spans.length).to be(thread_count)
end
end
end
end