def test_remotely_controlled_sampler():
    sampler = RemoteControlledSampler(channel=mock.MagicMock(),
                                      service_name='x')
    sampled, tags = sampler.is_sampled(1)
    assert sampled
    assert tags == get_tags('probabilistic', DEFAULT_SAMPLING_PROBABILITY)

    init_sampler = mock.MagicMock()
    init_sampler.is_sampled = mock.MagicMock()
    channel = mock.MagicMock()
    channel.io_loop = None
    sampler = RemoteControlledSampler(
        channel=channel,
        service_name='x',
        init_sampler=init_sampler,
        logger=mock.MagicMock(),
    )
    assert init_sampler.is_sampled.call_count == 1

    sampler.is_sampled(1)
    assert init_sampler.is_sampled.call_count == 2

    sampler.io_loop = mock.MagicMock()
    # noinspection PyProtectedMember
    sampler._init_polling()
    assert sampler.io_loop.call_later.call_count == 1

    sampler._create_periodic_callback = mock.MagicMock()
    # noinspection PyProtectedMember
    sampler._delayed_polling()
    sampler.close()
Esempio n. 2
0
def test_update_sampler_adaptive_sampler():
    error_reporter = mock.MagicMock()
    error_reporter.error = mock.MagicMock()
    remote_sampler = RemoteControlledSampler(
        channel=mock.MagicMock(),
        service_name='x',
        error_reporter=error_reporter,
        max_operations=10,
    )

    response = {
        "strategyType":"RATE_LIMITING",
        "operationSampling":
        {
            "defaultSamplingProbability":0.001,
            "defaultLowerBoundTracesPerSecond":2,
            "perOperationStrategies":
            [
                {
                    "operation":"op",
                    "probabilisticSampling":{
                        "samplingRate":0.002
                    }
                }
            ]
        }
    }

    remote_sampler._update_sampler(response)
    assert '%s' % remote_sampler.sampler == 'AdaptiveSampler(0.001000, 2.000000, 10)'

    new_response = {
        "strategyType":"RATE_LIMITING",
        "operationSampling":
        {
            "defaultSamplingProbability":0.51,
            "defaultLowerBoundTracesPerSecond":3,
            "perOperationStrategies":
            [
                {
                    "operation":"op",
                    "probabilisticSampling":{
                        "samplingRate":0.002
                    }
                }
            ]
        }
    }

    remote_sampler._update_sampler(new_response)
    assert '%s' % remote_sampler.sampler == 'AdaptiveSampler(0.510000, 3.000000, 10)'

    remote_sampler._update_sampler({"strategyType":"PROBABILISTIC","probabilisticSampling":{"samplingRate":0.004}})
    assert '%s' % remote_sampler.sampler == 'ProbabilisticSampler(0.004)', \
        'should not fail going from adaptive sampler to probabilistic sampler'

    remote_sampler._update_sampler({"strategyType":"RATE_LIMITING","operationSampling":{"defaultSamplingProbability":0.4}})
    assert '%s' % remote_sampler.sampler == 'AdaptiveSampler(0.400000, 0.001667, 10)'

    remote_sampler.close()
Esempio n. 3
0
def test_remotely_controlled_sampler():
    sampler = RemoteControlledSampler(
        channel=mock.MagicMock(),
        service_name='x'
    )
    sampled, tags = sampler.is_sampled(1)
    assert sampled
    assert tags == get_tags('probabilistic', DEFAULT_SAMPLING_PROBABILITY)

    init_sampler = mock.MagicMock()
    init_sampler.is_sampled = mock.MagicMock()
    channel = mock.MagicMock()
    channel.io_loop = None
    sampler = RemoteControlledSampler(
        channel=channel,
        service_name='x',
        init_sampler=init_sampler,
        logger=mock.MagicMock(),
    )
    assert init_sampler.is_sampled.call_count == 1

    sampler.is_sampled(1)
    assert init_sampler.is_sampled.call_count == 2

    sampler.io_loop = mock.MagicMock()
    # noinspection PyProtectedMember
    sampler._init_polling()
    assert sampler.io_loop.call_later.call_count == 1

    sampler._create_periodic_callback = mock.MagicMock()
    # noinspection PyProtectedMember
    sampler._delayed_polling()
    sampler.close()

    sampler = RemoteControlledSampler(
        channel=mock.MagicMock(),
        service_name='x',
        max_operations=None,
    )
    assert sampler.max_operations == DEFAULT_MAX_OPERATIONS

    sampler.close()
    assert not sampler.running
    sampler._init_polling()
    assert not sampler.running
    sampler._delayed_polling()
    assert not sampler.running
Esempio n. 4
0
def test_update_sampler(response, init_sampler, expected_sampler, err_count, err_msg, reference_equivalence, max_operations):
    error_reporter = mock.MagicMock()
    error_reporter.error = mock.MagicMock()
    remote_sampler = RemoteControlledSampler(
        channel=mock.MagicMock(),
        service_name='x',
        error_reporter=error_reporter,
        max_operations=max_operations,
        init_sampler=init_sampler,
    )

    # noinspection PyProtectedMember
    remote_sampler._update_sampler(response)
    assert error_reporter.error.call_count == err_count
    if reference_equivalence:
        assert remote_sampler.sampler is expected_sampler, err_msg
    else:
        assert remote_sampler.sampler == expected_sampler, err_msg

    remote_sampler.close()
Esempio n. 5
0
def test_update_sampler(response, init_sampler, expected_sampler,
                        err_count, err_msg, reference_equivalence, max_operations):
    error_reporter = mock.MagicMock()
    error_reporter.error = mock.MagicMock()
    remote_sampler = RemoteControlledSampler(
        channel=mock.MagicMock(),
        service_name='x',
        error_reporter=error_reporter,
        max_operations=max_operations,
        init_sampler=init_sampler,
    )

    # noinspection PyProtectedMember
    remote_sampler._update_sampler(response)
    assert error_reporter.error.call_count == err_count
    if reference_equivalence:
        assert remote_sampler.sampler is expected_sampler, err_msg
    else:
        assert remote_sampler.sampler == expected_sampler, err_msg

    remote_sampler.close()
Esempio n. 6
0
def test_sampling_request_callback():
    channel = mock.MagicMock()
    channel.io_loop = mock.MagicMock()
    error_reporter = mock.MagicMock()
    error_reporter.error = mock.MagicMock()
    sampler = RemoteControlledSampler(
        channel=channel,
        service_name='x',
        error_reporter=error_reporter,
        max_operations=10,
    )

    return_value = mock.MagicMock()
    return_value.exception = lambda *args: False

    probabilistic_strategy = """
    {
        "strategyType":"PROBABILISTIC",
        "probabilisticSampling":
        {
            "samplingRate":0.002
        }
    }
    """

    return_value.result = lambda *args: \
        type('obj', (object,), {'body': probabilistic_strategy})()
    sampler._sampling_request_callback(return_value)
    assert '%s' % sampler.sampler == 'ProbabilisticSampler(0.002)', 'sampler should have changed to probabilistic'
    prev_sampler = sampler.sampler

    sampler._sampling_request_callback(return_value)
    assert prev_sampler is sampler.sampler, "strategy hasn't changed so sampler should not change"

    adaptive_sampling_strategy = """
    {
        "strategyType":"PROBABILISTIC",
        "operationSampling":
        {
            "defaultSamplingProbability":0.001,
            "defaultLowerBoundTracesPerSecond":2,
            "perOperationStrategies":
            [
                {
                    "operation":"op",
                    "probabilisticSampling":{
                        "samplingRate":0.002
                    }
                }
            ]
        }
    }
    """
    return_value.result = lambda *args: \
        type('obj', (object,), {'body': adaptive_sampling_strategy})()
    sampler._sampling_request_callback(return_value)
    assert '%s' % sampler.sampler == 'AdaptiveSampler(0.001000, 2.000000, 10)', 'sampler should have changed to adaptive'
    prev_sampler = sampler.sampler

    sampler._sampling_request_callback(return_value)
    assert prev_sampler is sampler.sampler, "strategy hasn't changed so sampler should not change"

    probabilistic_strategy_bytes = probabilistic_strategy.encode('utf-8')

    return_value.result = lambda *args: \
        type('obj', (object,), {'body': probabilistic_strategy_bytes})()
    sampler._sampling_request_callback(return_value)
    assert '%s' % sampler.sampler == 'ProbabilisticSampler(0.002)', 'sampler should have changed to probabilistic'

    adaptive_sampling_strategy_bytearray = bytearray(adaptive_sampling_strategy.encode('utf-8'))

    return_value.result = lambda *args: \
        type('obj', (object,), {'body': adaptive_sampling_strategy_bytearray})()
    sampler._sampling_request_callback(return_value)
    assert '%s' % sampler.sampler == 'AdaptiveSampler(0.001000, 2.000000, 10)', 'sampler should have changed to adaptive'
    prev_sampler = sampler.sampler

    return_value.exception = lambda *args: True
    sampler._sampling_request_callback(return_value)
    assert error_reporter.error.call_count == 1
    assert prev_sampler is sampler.sampler, 'error fetching strategy should not update the sampler'

    return_value.exception = lambda *args: False
    return_value.result = lambda *args: type('obj', (object,), {'body': 'bad_json'})()

    sampler._sampling_request_callback(return_value)
    assert error_reporter.error.call_count == 2
    assert prev_sampler is sampler.sampler, 'error updating sampler should not update the sampler'

    return_value.result = lambda *args: \
        type('obj', (object,), {'body': None})()
    sampler._sampling_request_callback(return_value)
    assert error_reporter.error.call_count == 3
    assert prev_sampler is sampler.sampler, 'error updating sampler should not update the sampler'

    return_value.result = lambda *args: \
        type('obj', (object,), {'body': {'decode': None}})()
    sampler._sampling_request_callback(return_value)
    assert error_reporter.error.call_count == 4
    assert prev_sampler is sampler.sampler, 'error updating sampler should not update the sampler'

    return_value.result = lambda *args: \
        type('obj', (object,), {'body': probabilistic_strategy})()
    sampler._sampling_request_callback(return_value)
    assert '%s' % sampler.sampler == 'ProbabilisticSampler(0.002)', 'updating sampler from adaptive to probabilistic should work'

    sampler.close()
Esempio n. 7
0
def test_update_sampler_adaptive_sampler():
    error_reporter = mock.MagicMock()
    error_reporter.error = mock.MagicMock()
    remote_sampler = RemoteControlledSampler(
        channel=mock.MagicMock(),
        service_name='x',
        error_reporter=error_reporter,
        max_operations=10,
    )

    response = {
        'strategyType': 'RATE_LIMITING',
        'operationSampling': {
            'defaultSamplingProbability':
            0.001,
            'defaultLowerBoundTracesPerSecond':
            2,
            'perOperationStrategies': [{
                'operation': 'op',
                'probabilisticSampling': {
                    'samplingRate': 0.002
                }
            }]
        }
    }

    remote_sampler._update_sampler(response)
    assert '%s' % remote_sampler.sampler == 'AdaptiveSampler(0.001000, 2.000000, 10)'

    new_response = {
        'strategyType': 'RATE_LIMITING',
        'operationSampling': {
            'defaultSamplingProbability':
            0.51,
            'defaultLowerBoundTracesPerSecond':
            3,
            'perOperationStrategies': [{
                'operation': 'op',
                'probabilisticSampling': {
                    'samplingRate': 0.002
                }
            }]
        }
    }

    remote_sampler._update_sampler(new_response)
    assert '%s' % remote_sampler.sampler == 'AdaptiveSampler(0.510000, 3.000000, 10)'

    remote_sampler._update_sampler({
        'strategyType': 'PROBABILISTIC',
        'probabilisticSampling': {
            'samplingRate': 0.004
        }
    })
    assert '%s' % remote_sampler.sampler == 'ProbabilisticSampler(0.004)', \
        'should not fail going from adaptive sampler to probabilistic sampler'

    remote_sampler._update_sampler({
        'strategyType': 'RATE_LIMITING',
        'operationSampling': {
            'defaultSamplingProbability': 0.4
        }
    })
    assert '%s' % remote_sampler.sampler == 'AdaptiveSampler(0.400000, 0.001667, 10)'

    remote_sampler.close()
Esempio n. 8
0
def test_update_sampler_adaptive_sampler():
    error_reporter = mock.MagicMock()
    error_reporter.error = mock.MagicMock()
    remote_sampler = RemoteControlledSampler(
        channel=mock.MagicMock(),
        service_name='x',
        error_reporter=error_reporter,
        max_operations=10,
    )

    response = {
        'strategyType': 'RATE_LIMITING',
        'operationSampling':
        {
            'defaultSamplingProbability': 0.001,
            'defaultLowerBoundTracesPerSecond': 2,
            'perOperationStrategies':
            [
                {
                    'operation': 'op',
                    'probabilisticSampling': {
                        'samplingRate': 0.002
                    }
                }
            ]
        }
    }

    remote_sampler._update_sampler(response)
    assert '%s' % remote_sampler.sampler == 'AdaptiveSampler(0.001000, 2.000000, 10)'

    new_response = {
        'strategyType': 'RATE_LIMITING',
        'operationSampling':
        {
            'defaultSamplingProbability': 0.51,
            'defaultLowerBoundTracesPerSecond': 3,
            'perOperationStrategies':
            [
                {
                    'operation': 'op',
                    'probabilisticSampling': {
                        'samplingRate': 0.002
                    }
                }
            ]
        }
    }

    remote_sampler._update_sampler(new_response)
    assert '%s' % remote_sampler.sampler == 'AdaptiveSampler(0.510000, 3.000000, 10)'

    remote_sampler._update_sampler(
        {'strategyType': 'PROBABILISTIC', 'probabilisticSampling': {'samplingRate': 0.004}})
    assert '%s' % remote_sampler.sampler == 'ProbabilisticSampler(0.004)', \
        'should not fail going from adaptive sampler to probabilistic sampler'

    remote_sampler._update_sampler({'strategyType': 'RATE_LIMITING',
                                    'operationSampling': {'defaultSamplingProbability': 0.4}})
    assert '%s' % remote_sampler.sampler == 'AdaptiveSampler(0.400000, 0.001667, 10)'

    remote_sampler.close()
Esempio n. 9
0
def test_sampling_request_callback():
    channel = mock.MagicMock()
    channel.io_loop = mock.MagicMock()
    error_reporter = mock.MagicMock()
    error_reporter.error = mock.MagicMock()
    sampler = RemoteControlledSampler(
        channel=channel,
        service_name='x',
        error_reporter=error_reporter,
        max_operations=10,
    )

    return_value = mock.MagicMock()
    return_value.exception = lambda *args: False

    probabilistic_strategy = """
    {
        "strategyType":"PROBABILISTIC",
        "probabilisticSampling":
        {
            "samplingRate":0.002
        }
    }
    """

    return_value.result = lambda *args: \
        type('obj', (object,), {'body': probabilistic_strategy})()
    sampler._sampling_request_callback(return_value)
    assert '%s' % sampler.sampler == \
           'ProbabilisticSampler(0.002)', 'sampler should have changed to probabilistic'
    prev_sampler = sampler.sampler

    sampler._sampling_request_callback(return_value)
    assert prev_sampler is sampler.sampler, \
        "strategy hasn't changed so sampler should not change"

    adaptive_sampling_strategy = """
    {
        "strategyType":"PROBABILISTIC",
        "operationSampling":
        {
            "defaultSamplingProbability":0.001,
            "defaultLowerBoundTracesPerSecond":2,
            "perOperationStrategies":
            [
                {
                    "operation":"op",
                    "probabilisticSampling":{
                        "samplingRate":0.002
                    }
                }
            ]
        }
    }
    """
    return_value.result = lambda *args: \
        type('obj', (object,), {'body': adaptive_sampling_strategy})()
    sampler._sampling_request_callback(return_value)
    assert '%s' % sampler.sampler == 'AdaptiveSampler(0.001000, 2.000000, 10)', \
        'sampler should have changed to adaptive'
    prev_sampler = sampler.sampler

    sampler._sampling_request_callback(return_value)
    assert prev_sampler is sampler.sampler, "strategy hasn't changed so sampler should not change"

    probabilistic_strategy_bytes = probabilistic_strategy.encode('utf-8')

    return_value.result = lambda *args: \
        type('obj', (object,), {'body': probabilistic_strategy_bytes})()
    sampler._sampling_request_callback(return_value)
    assert '%s' % sampler.sampler == \
           'ProbabilisticSampler(0.002)', 'sampler should have changed to probabilistic'

    adaptive_sampling_strategy_bytearray = bytearray(adaptive_sampling_strategy.encode('utf-8'))

    return_value.result = lambda *args: \
        type('obj', (object,), {'body': adaptive_sampling_strategy_bytearray})()
    sampler._sampling_request_callback(return_value)
    assert '%s' % sampler.sampler == 'AdaptiveSampler(0.001000, 2.000000, 10)', \
        'sampler should have changed to adaptive'
    prev_sampler = sampler.sampler

    return_value.exception = lambda *args: True
    sampler._sampling_request_callback(return_value)
    assert error_reporter.error.call_count == 1
    assert prev_sampler is sampler.sampler, 'error fetching strategy should not update the sampler'

    return_value.exception = lambda *args: False
    return_value.result = lambda *args: type('obj', (object,), {'body': 'bad_json'})()

    sampler._sampling_request_callback(return_value)
    assert error_reporter.error.call_count == 2
    assert prev_sampler is sampler.sampler, 'error updating sampler should not update the sampler'

    return_value.result = lambda *args: \
        type('obj', (object,), {'body': None})()
    sampler._sampling_request_callback(return_value)
    assert error_reporter.error.call_count == 3
    assert prev_sampler is sampler.sampler, 'error updating sampler should not update the sampler'

    return_value.result = lambda *args: \
        type('obj', (object,), {'body': {'decode': None}})()
    sampler._sampling_request_callback(return_value)
    assert error_reporter.error.call_count == 4
    assert prev_sampler is sampler.sampler, 'error updating sampler should not update the sampler'

    return_value.result = lambda *args: \
        type('obj', (object,), {'body': probabilistic_strategy})()
    sampler._sampling_request_callback(return_value)
    assert '%s' % sampler.sampler == 'ProbabilisticSampler(0.002)', \
        'updating sampler from adaptive to probabilistic should work'

    sampler.close()
def test_parse_sampling_strategy():
    sampler = RemoteControlledSampler(
        channel=mock.MagicMock(),
        service_name='x',
        max_operations=10
    )
    # noinspection PyProtectedMember
    s, strategies = sampler._parse_sampling_strategy(None, '{"strategyType":0,"probabilisticSampling":{"samplingRate":0.001}}')
    assert '%s' % s == 'ProbabilisticSampler(0.001)'
    assert not strategies

    with pytest.raises(ValueError):
        # noinspection PyProtectedMember
        sampler._parse_sampling_strategy(None,'{"strategyType":0,"probabilisticSampling":{"samplingRate":2}}')

    # noinspection PyProtectedMember
    s, strategies = sampler._parse_sampling_strategy(None, '{"strategyType":1,"rateLimitingSampling":{"maxTracesPerSecond":10}}')
    assert '%s' % s == 'RateLimitingSampler(10)'
    assert not strategies

    with pytest.raises(ValueError):
        # noinspection PyProtectedMember
        sampler._parse_sampling_strategy(None, '{"strategyType":1,"rateLimitingSampling":{"maxTracesPerSecond":-10}}')

    with pytest.raises(ValueError):
        # noinspection PyProtectedMember
        sampler._parse_sampling_strategy(None, '{"strategyType":2}')

    response = """
    {
        "strategyType":1,
        "operationSampling":
        {
            "defaultSamplingProbability":0.001,
            "defaultLowerBoundTracesPerSecond":2,
            "perOperationStrategies":
            [
                {
                    "operation":"op",
                    "probabilisticSampling":{
                        "samplingRate":0.002
                    }
                }
            ]
        }
    }
    """
    # noinspection PyProtectedMember
    s, strategies = sampler._parse_sampling_strategy(None, response)
    assert '%s' % s == 'AdaptiveSampler(0.001, 2, 10)'
    assert strategies

    existing_strategies = {
        "defaultSamplingProbability":0.51,
        "defaultLowerBoundTracesPerSecond":3,
        "perOperationStrategies":
            [
                {
                    "operation":"op",
                    "probabilisticSampling":{
                        "samplingRate":0.5
                    }
                }
            ]
    }
    existing_sampler = AdaptiveSampler(existing_strategies, 2)
    assert '%s' % existing_sampler == 'AdaptiveSampler(0.51, 3, 2)'

    # noinspection PyProtectedMember
    s, strategies = sampler._parse_sampling_strategy(existing_sampler, response)
    assert '%s' % existing_sampler == 'AdaptiveSampler(0.51, 3, 2)'
    assert strategies

    sampler.close()
def test_sampling_request_callback():
    channel = mock.MagicMock()
    channel.io_loop = mock.MagicMock()
    error_reporter = mock.MagicMock()
    error_reporter.error = mock.MagicMock()
    sampler = RemoteControlledSampler(
        channel=channel,
        service_name='x',
        error_reporter=error_reporter,
        max_operations=10,
    )

    return_value = mock.MagicMock()
    return_value.exception = lambda *args: False
    return_value.result = lambda *args: type('obj', (object,), {'body': 'bad_json'})()

    # noinspection PyProtectedMember
    sampler._sampling_request_callback(return_value)
    assert error_reporter.error.call_count == 1

    # Strategy has changed to new probabilistic sampler
    return_value.result = lambda *args: \
        type('obj', (object,), {'body': '{"strategyType":0,"probabilisticSampling":{"samplingRate":0.002}}'})()
    # noinspection PyProtectedMember
    sampler._sampling_request_callback(return_value)
    assert '%s' % sampler.sampler == 'ProbabilisticSampler(0.002)'

    # Strategy hasn't changed
    # noinspection PyProtectedMember
    sampler._sampling_request_callback(return_value)
    assert '%s' % sampler.sampler == 'ProbabilisticSampler(0.002)'

    # Strategy changed to AdaptiveSampler
    strategy = """
    {
        "strategyType":1,
        "operationSampling":
        {
            "defaultSamplingProbability":0.001,
            "defaultLowerBoundTracesPerSecond":2,
            "perOperationStrategies":
            [
                {
                    "operation":"op",
                    "probabilisticSampling":{
                        "samplingRate":0.002
                    }
                }
            ]
        }
    }
    """
    return_value.result = lambda *args: \
        type('obj', (object,), {'body': strategy})()
    # noinspection PyProtectedMember
    sampler._sampling_request_callback(return_value)
    assert '%s' % sampler.sampler == 'AdaptiveSampler(0.001, 2, 10)'

    # Strategy hasn't changed
    # noinspection PyProtectedMember
    sampler._sampling_request_callback(return_value)
    assert '%s' % sampler.sampler == 'AdaptiveSampler(0.001, 2, 10)'

    return_value.exception = lambda *args: True
    # noinspection PyProtectedMember
    sampler._sampling_request_callback(return_value)
    assert error_reporter.error.call_count == 2

    sampler.close()