Skip to content

Commit

Permalink
Merge pull request #3173 from DataDog/spec-helpers-cleanup
Browse files Browse the repository at this point in the history
Cleanup the number of helper methods that are available for all specs
  • Loading branch information
GustavoCaso authored Oct 2, 2023
2 parents 70bad1d + b087037 commit 6a3a9e7
Show file tree
Hide file tree
Showing 72 changed files with 114 additions and 607 deletions.
18 changes: 16 additions & 2 deletions spec/datadog/core/buffer/shared_examples.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,14 @@
let(:barrier) { Concurrent::CyclicBarrier.new(thread_count + 1) }

before do
allow(Datadog).to receive(:logger).and_return(double)
logger = double(Datadog::Core::Logger)
allow(logger).to receive(:debug?).and_return true
allow(logger).to receive(:debug)
allow(logger).to receive(:info)
allow(logger).to receive(:warn)
allow(logger).to receive(:error)

allow(Datadog).to receive(:logger).and_return(logger)
end

it 'executes without error' do
Expand Down Expand Up @@ -136,7 +143,14 @@
let(:barrier) { Concurrent::CyclicBarrier.new(thread_count + 1) }

before do
allow(Datadog).to receive(:logger).and_return(double)
logger = double(Datadog::Core::Logger)
allow(logger).to receive(:debug?).and_return true
allow(logger).to receive(:debug)
allow(logger).to receive(:info)
allow(logger).to receive(:warn)
allow(logger).to receive(:error)

allow(Datadog).to receive(:logger).and_return(logger)
end

it 'executes without error' do
Expand Down
1 change: 1 addition & 0 deletions spec/datadog/core/environment/cgroup_spec.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'spec_helper'
require 'support/container_helpers'
require 'datadog/core/environment/cgroup'

# rubocop:disable Layout/LineLength
Expand Down
1 change: 1 addition & 0 deletions spec/datadog/core/environment/container_spec.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'spec_helper'
require 'support/container_helpers'
require 'datadog/core/environment/container'

RSpec.describe Datadog::Core::Environment::Container do
Expand Down
3 changes: 1 addition & 2 deletions spec/datadog/core/metrics/client_spec.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
require 'spec_helper'

require 'datadog/statsd'

require 'datadog/core/metrics/client'
require 'support/metric_helpers'

RSpec.describe Datadog::Core::Metrics::Client do
include_context 'metrics'
Expand Down
1 change: 1 addition & 0 deletions spec/datadog/opentracer/propagation_integration_spec.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'spec_helper'
require 'support/rack_support'

require 'datadog/tracing/utils'
require 'datadog/opentracer'
Expand Down
2 changes: 0 additions & 2 deletions spec/datadog/profiling_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
require 'datadog/profiling'

RSpec.describe Datadog::Profiling do
extend ConfigurationHelpers

describe '.start_if_enabled' do
subject(:start_if_enabled) { described_class.start_if_enabled }

Expand Down
288 changes: 1 addition & 287 deletions spec/datadog/tracing/buffer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

require 'datadog/core'
require 'datadog/tracing/buffer'
require 'spec/datadog/core/buffer/shared_examples'

RSpec.describe Datadog::Tracing::TraceBuffer do
subject(:buffer_class) { described_class }
Expand All @@ -22,169 +23,6 @@
end
end

RSpec.shared_examples 'thread-safe buffer' do
subject(:buffer) { described_class.new(max_size) }

let(:max_size) { 0 }
let(:items) { defined?(super) ? super() : Array.new(items_count) { double('item') } }
let(:items_count) { 10 }

describe '#push' do
subject(:push) { threads.each(&:join) }

let(:output) { buffer.pop }
let(:wait_for_threads) { threads.each { |t| raise 'Thread wait timeout' unless t.join(5000) } }
let(:max_size) { 500 }
let(:thread_count) { 100 }
let(:threads) do
buffer
items

Array.new(thread_count) do |_i|
Thread.new do
sleep(rand / 1000.0)
buffer.push(items)
end
end
end

it 'does not have collisions' do
push
expect(output).to_not be nil
expect(output).to match_array(Array.new(thread_count) { items })
end

context 'with items exceeding maximum size' do
let(:max_size) { 100 }
let(:thread_count) { 100 }
let(:barrier) { Concurrent::CyclicBarrier.new(thread_count) }
let(:threads) do
buffer
barrier
items

Array.new(thread_count) do |_i|
Thread.new do
barrier.wait
1000.times { buffer.push(items) }
end
end
end

it 'does not exceed expected maximum size' do
push
expect(output).to have_at_most(max_size).items
end

context 'with #pop operations' do
let(:barrier) { Concurrent::CyclicBarrier.new(thread_count + 1) }

it 'executes without error' do
threads

barrier.wait
1000.times do
buffer.pop

# Yield control to threads to increase contention.
# Otherwise we might run #pop a few times in succession,
# which doesn't help us stress test this case.
Thread.pass
end

push
end
end
end
end

describe '#concat' do
subject(:concat) { wait_for_threads }
let(:output) { buffer.pop }
let(:wait_for_threads) { threads.each { |t| raise 'Thread wait timeout' unless t.join(5000) } }
let(:bulk_items) { Array.new(10, items) }
let(:max_size) { 5000 }
let(:thread_count) { 100 }
let(:threads) do
buffer
bulk_items

Array.new(thread_count) do |_i|
Thread.new do
sleep(rand / 1000.0)
buffer.concat(bulk_items)
end
end
end

it 'does not have collisions' do
concat
expect(output).to_not be nil
expect(output).to match_array(thread_count.times.flat_map { bulk_items })
end

context 'with items exceeding maximum size' do
let(:max_size) { 100 }
let(:thread_count) { 100 }
let(:items_count) { 10 }
let(:barrier) { Concurrent::CyclicBarrier.new(thread_count) }
let(:threads) do
buffer
barrier
items

Array.new(thread_count) do |_i|
Thread.new do
barrier.wait
500.times { buffer.concat(items) }
end
end
end

it 'does not exceed expected maximum size' do
concat
expect(output).to have_at_most(max_size).items
end

context 'with #pop operations' do
let(:barrier) { Concurrent::CyclicBarrier.new(thread_count + 1) }

it 'executes without error' do
threads

barrier.wait
1000.times do
buffer.pop

# Yield control to threads to increase contention.
# Otherwise we might run #pop a few times in succession,
# which doesn't help us stress test this case.
Thread.pass
end

concat
end
end
end
end

describe '#pop' do
subject(:pop) { buffer.pop }

let(:traces) { get_test_traces(2) }

before do
traces.each { |t| buffer.push(t) }
end

it do
expect(pop.length).to eq(traces.length)
expect(pop).to include(*traces)
expect(buffer.empty?).to be true
end
end
end

RSpec.shared_examples 'trace buffer' do
include_context 'health metrics'

Expand Down Expand Up @@ -309,130 +147,6 @@ def measure_trace_size(trace)
end
end

# :nocov:
RSpec.shared_examples 'performance' do
subject(:buffer) { described_class.new(max_size) }

let(:max_size) { 0 }

require 'benchmark'
let(:n) { 10_000 }
let(:test_item_count) { 20 }

def get_test_items(n = 1)
Array.new(n) { double('item') }
end

before { skip('Performance test does not run in CI.') }

context 'no max_size' do
it do
Benchmark.bmbm do |x|
x.report('No max #push') do
n.times do
buffer = described_class.new(max_size)
items = get_test_items(test_item_count)

items.each { |item| buffer.push(item) }
end
end

x.report('No max #concat') do
n.times do
buffer = described_class.new(max_size)
items = get_test_items(test_item_count)

buffer.concat(items)
end
end
end
end
end

context 'max size' do
let(:max_size) { 20 }

context 'no overflow' do
let(:test_item_count) { max_size }

it do
Benchmark.bmbm do |x|
x.report('Max no overflow #push') do
n.times do
buffer = described_class.new(max_size)
items = get_test_items(test_item_count)

items.each { |item| buffer.push(item) }
end
end

x.report('Max no overflow #concat') do
n.times do
buffer = described_class.new(max_size)
items = get_test_items(test_item_count)

buffer.concat(items)
end
end
end
end
end

context 'partial overflow' do
let(:test_item_count) { max_size + super() }

it do
Benchmark.bmbm do |x|
x.report('Max partial overflow #push') do
n.times do
buffer = described_class.new(max_size)
items = get_test_items(test_item_count)

items.each { |item| buffer.push(item) }
end
end

x.report('Max partial overflow #concat') do
n.times do
buffer = described_class.new(max_size)
items = get_test_items(test_item_count)

buffer.concat(items)
end
end
end
end
end

context 'total overflow' do
it do
Benchmark.bmbm do |x|
x.report('Max total overflow #push') do
n.times do
buffer = described_class.new(max_size)
buffer.instance_variable_set(:@items, get_test_items(max_size))
items = get_test_items(test_item_count)

items.each { |item| buffer.push(item) }
end
end

x.report('Max total overflow #concat') do
n.times do
buffer = described_class.new(max_size)
buffer.instance_variable_set(:@items, get_test_items(max_size))
items = get_test_items(test_item_count)

buffer.concat(items)
end
end
end
end
end
end
end
# :nocov:

RSpec.describe Datadog::Tracing::ThreadSafeTraceBuffer do
let(:items) { get_test_traces(items_count) }

Expand Down
Loading

0 comments on commit 6a3a9e7

Please sign in to comment.