# frozen_string_literal: true require 'test_helper' class AssertionsTest < Minitest::Test def setup @old_client = StatsD.singleton_client env = StatsD::Instrument::Environment.new('STATSD_IMPLEMENTATION' => 'datadog') StatsD.singleton_client = StatsD::Instrument::Client.from_env(env) test_class = Class.new(Minitest::Test) test_class.send(:include, StatsD::Instrument::Assertions) @test_case = test_class.new('fake') end def teardown StatsD.singleton_client = @old_client end def test_assert_no_statsd_calls @test_case.assert_no_statsd_calls('counter') do # noop end @test_case.assert_no_statsd_calls('counter') do StatsD.increment('other') end assertion = assert_raises(Minitest::Assertion) do @test_case.assert_no_statsd_calls('counter') do StatsD.increment('counter') end end assert_equal assertion.message, "No StatsD calls for metric counter expected." @test_case.assert_no_statsd_calls('counter1', 'counter2') do # noop end @test_case.assert_no_statsd_calls('counter1', 'counter2') do StatsD.increment('counter') end assertion = assert_raises(Minitest::Assertion) do @test_case.assert_no_statsd_calls('counter1', 'counter2') do StatsD.increment('counter0') StatsD.increment('counter1') StatsD.increment('counter2') StatsD.increment('counter3') end end assert_equal assertion.message, "No StatsD calls for metric counter1, counter2 expected." assertion = assert_raises(Minitest::Assertion) do @test_case.assert_no_statsd_calls('counter0', 'counter1', 'counter2') do StatsD.increment('counter1') end end assert_equal assertion.message, "No StatsD calls for metric counter1 expected." assertion = assert_raises(Minitest::Assertion) do @test_case.assert_no_statsd_calls do StatsD.increment('other') end end assert_equal assertion.message, "No StatsD calls for metric other expected." assertion = assert_raises(Minitest::Assertion) do @test_case.assert_no_statsd_calls do StatsD.increment('other') StatsD.increment('another') end end assert_equal assertion.message, "No StatsD calls for metric other, another expected." end def test_assert_statsd @test_case.assert_statsd_increment('counter') do StatsD.increment('counter') end @test_case.assert_statsd_increment('counter') do StatsD.increment('counter') StatsD.increment('other') end assert_raises(Minitest::Assertion) do @test_case.assert_statsd_increment('counter') do StatsD.increment('other') end end assert_raises(Minitest::Assertion) do @test_case.assert_statsd_increment('counter') do StatsD.gauge('counter', 42) end end assert_raises(Minitest::Assertion) do @test_case.assert_statsd_increment('counter') do StatsD.increment('counter') StatsD.increment('counter') end end @test_case.assert_statsd_increment('counter', times: 2) do StatsD.increment('counter') StatsD.increment('counter') end @test_case.assert_statsd_increment('counter', times: 2, tags: ['foo:1']) do StatsD.increment('counter', tags: { foo: 1 }) StatsD.increment('counter', tags: { foo: 1 }) end assert_raises(Minitest::Assertion) do @test_case.assert_statsd_increment('counter', times: 2, tags: ['foo:1']) do StatsD.increment('counter', tags: { foo: 1 }) StatsD.increment('counter', tags: { foo: 2 }) end end @test_case.assert_statsd_increment('counter', sample_rate: 0.5, tags: ['a', 'b']) do StatsD.increment('counter', sample_rate: 0.5, tags: ['a', 'b']) end assert_raises(Minitest::Assertion) do @test_case.assert_statsd_increment('counter', sample_rate: 0.5, tags: ['a', 'b']) do StatsD.increment('counter', sample_rate: 0.2, tags: ['c']) end end end def test_assert_statsd_gauge_call_with_numeric_value @test_case.assert_statsd_gauge('gauge', 42) do StatsD.gauge('gauge', 42) end @test_case.assert_statsd_gauge('gauge', '42') do StatsD.gauge('gauge', 42) end assert_raises(Minitest::Assertion) do @test_case.assert_statsd_gauge('gauge', 42) do StatsD.gauge('gauge', 45) end end @test_case.assert_statsd_gauge('gauge', value: 42) do StatsD.gauge('gauge', 42) end end def test_assert_statsd_set_call_with_string_value @test_case.assert_statsd_set('set', 12345) do StatsD.set('set', '12345') end @test_case.assert_statsd_set('set', '12345') do StatsD.set('set', '12345') end @test_case.assert_statsd_set('set', 12345) do StatsD.set('set', 12345) end @test_case.assert_statsd_set('set', '12345') do StatsD.set('set', 12345) end assert_raises(Minitest::Assertion) do @test_case.assert_statsd_set('set', '42') do StatsD.set('set', 45) end end @test_case.assert_statsd_set('set', value: 12345) do StatsD.set('set', '12345') end @test_case.assert_statsd_set('set', 'wrong_value', value: 12345) do StatsD.set('set', '12345') end end def test_tags_will_match_subsets @test_case.assert_statsd_increment('counter', sample_rate: 0.5, tags: { a: 1 }) do StatsD.increment('counter', sample_rate: 0.5, tags: { a: 1, b: 2 }) end assert_raises(Minitest::Assertion) do @test_case.assert_statsd_increment('counter', sample_rate: 0.5, tags: { a: 1, b: 3 }) do StatsD.increment('counter', sample_rate: 0.5, tags: { a: 1, b: 2, c: 4 }) end end end def test_tags_friendly_error assertion = assert_raises(Minitest::Assertion) do @test_case.assert_statsd_increment('counter', tags: { class: "AnotherJob" }) do StatsD.increment('counter', tags: { class: "MyJob" }) end end assert_includes assertion.message, "Captured metrics with the same key" assert_includes assertion.message, "MyJob" end def test_capture_and_assert datagrams = @test_case.capture_statsd_datagrams do StatsD.increment('counter', tags: { foo: 1 }) StatsD.increment('counter', tags: { foo: 2 }) end @test_case.assert_statsd_increment('counter', tags: ['foo:1'], datagrams: datagrams) @test_case.assert_statsd_increment('counter', tags: ['foo:2'], datagrams: datagrams) end def test_capture_from_different_client client = StatsD::Instrument::Client.new @test_case.assert_statsd_increment('foo', client: client) do client.increment('foo') end assert_raises(Minitest::Assertion) do @test_case.assert_statsd_increment('foo', client: client) do StatsD.increment('foo') end end assert_raises(Minitest::Assertion) do @test_case.assert_statsd_increment('foo') do client.increment('foo') end end end def test_multiple_expectations_are_not_order_dependent foo_1_metric = StatsD::Instrument::Expectation.increment('counter', tags: ['foo:1']) foo_2_metric = StatsD::Instrument::Expectation.increment('counter', tags: ['foo:2']) @test_case.assert_statsd_expectations([foo_1_metric, foo_2_metric]) do StatsD.increment('counter', tags: { foo: 1 }) StatsD.increment('counter', tags: { foo: 2 }) end foo_1_metric = StatsD::Instrument::Expectation.increment('counter', tags: ['foo:1']) foo_2_metric = StatsD::Instrument::Expectation.increment('counter', tags: ['foo:2']) @test_case.assert_statsd_expectations([foo_2_metric, foo_1_metric]) do StatsD.increment('counter', tags: { foo: 1 }) StatsD.increment('counter', tags: { foo: 2 }) end foo_1_metric = StatsD::Instrument::Expectation.increment('counter', times: 2, tags: ['foo:1']) foo_2_metric = StatsD::Instrument::Expectation.increment('counter', tags: ['foo:2']) @test_case.assert_statsd_expectations([foo_1_metric, foo_2_metric]) do StatsD.increment('counter', tags: { foo: 1 }) StatsD.increment('counter', tags: { foo: 1 }) StatsD.increment('counter', tags: { foo: 2 }) end foo_1_metric = StatsD::Instrument::Expectation.increment('counter', times: 2, tags: ['foo:1']) foo_2_metric = StatsD::Instrument::Expectation.increment('counter', tags: ['foo:2']) @test_case.assert_statsd_expectations([foo_2_metric, foo_1_metric]) do StatsD.increment('counter', tags: { foo: 1 }) StatsD.increment('counter', tags: { foo: 1 }) StatsD.increment('counter', tags: { foo: 2 }) end foo_1_metric = StatsD::Instrument::Expectation.increment('counter', times: 2, tags: ['foo:1']) foo_2_metric = StatsD::Instrument::Expectation.increment('counter', tags: ['foo:2']) @test_case.assert_statsd_expectations([foo_2_metric, foo_1_metric]) do StatsD.increment('counter', tags: { foo: 1 }) StatsD.increment('counter', tags: { foo: 2 }) StatsD.increment('counter', tags: { foo: 1 }) end end def test_assert_multiple_statsd_expectations assert_raises(Minitest::Assertion) do foo_1_metric = StatsD::Instrument::Expectation.increment('counter', times: 2, tags: ['foo:1']) foo_2_metric = StatsD::Instrument::Expectation.increment('counter', tags: ['foo:2']) @test_case.assert_statsd_expectations([foo_1_metric, foo_2_metric]) do StatsD.increment('counter', tags: { foo: 1 }) StatsD.increment('counter', tags: { foo: 2 }) end end assert_raises(Minitest::Assertion) do foo_1_metric = StatsD::Instrument::Expectation.increment('counter', times: 2, tags: ['foo:1']) foo_2_metric = StatsD::Instrument::Expectation.increment('counter', tags: ['foo:2']) @test_case.assert_statsd_expectations([foo_1_metric, foo_2_metric]) do StatsD.increment('counter', tags: { foo: 1 }) StatsD.increment('counter', tags: { foo: 1 }) StatsD.increment('counter', tags: { foo: 2 }) StatsD.increment('counter', tags: { foo: 2 }) end end foo_1_metric = StatsD::Instrument::Expectation.increment('counter', times: 2, tags: ['foo:1']) foo_2_metric = StatsD::Instrument::Expectation.increment('counter', 1, tags: ['foo:2']) @test_case.assert_statsd_expectations([foo_1_metric, foo_2_metric]) do StatsD.increment('counter', tags: { foo: 1 }) StatsD.increment('counter', tags: { foo: 1 }) StatsD.increment('counter', tags: { foo: 2 }) end end def test_assert_statsd_increment_with_tags @test_case.assert_statsd_increment('counter', tags: ['a:b', 'c:d']) do StatsD.increment('counter', tags: { a: 'b', c: 'd' }) end @test_case.assert_statsd_increment('counter', tags: { a: 'b', c: 'd' }) do StatsD.increment('counter', tags: ['a:b', 'c:d']) end end def test_nested_assertions @test_case.assert_statsd_increment('counter1') do @test_case.assert_statsd_increment('counter2') do StatsD.increment('counter1') StatsD.increment('counter2') end end @test_case.assert_statsd_increment('counter1') do StatsD.increment('counter1') @test_case.assert_statsd_increment('counter2') do StatsD.increment('counter2') end end assert_raises(Minitest::Assertion) do @test_case.assert_statsd_increment('counter1') do @test_case.assert_statsd_increment('counter2') do StatsD.increment('counter2') end end end assert_raises(Minitest::Assertion) do @test_case.assert_statsd_increment('counter1') do @test_case.assert_statsd_increment('counter2') do StatsD.increment('counter1') end StatsD.increment('counter2') end end end def test_assertion_block_with_expected_exceptions @test_case.assert_statsd_increment('expected_happened') do @test_case.assert_raises(RuntimeError) do begin raise "expected" rescue StatsD.increment('expected_happened') raise end end end assertion = assert_raises(Minitest::Assertion) do @test_case.assert_statsd_increment('counter') do @test_case.assert_raises(RuntimeError) do raise "expected" end end end assert_includes assertion.message, "No StatsD calls for metric counter of type c were made" end def test_assertion_block_with_unexpected_exceptions assertion = assert_raises(Minitest::Assertion) do @test_case.assert_statsd_increment('counter') do StatsD.increment('counter') raise "unexpected" end end assert_includes assertion.message, "An exception occurred in the block provided to the StatsD assertion" assertion = assert_raises(Minitest::Assertion) do @test_case.assert_raises(RuntimeError) do @test_case.assert_statsd_increment('counter') do StatsD.increment('counter') raise "unexpected" end end end assert_includes assertion.message, "An exception occurred in the block provided to the StatsD assertion" assertion = assert_raises(Minitest::Assertion) do @test_case.assert_raises(RuntimeError) do @test_case.assert_no_statsd_calls do raise "unexpected" end end end assert_includes assertion.message, "An exception occurred in the block provided to the StatsD assertion" end def test_assertion_block_with_other_assertion_failures # If another assertion failure happens inside the block, that failure should have priority assertion = assert_raises(Minitest::Assertion) do @test_case.assert_statsd_increment('counter') do @test_case.flunk('other assertion failure') end end assert_equal "other assertion failure", assertion.message end end