def test_full_init():
    # Setup test data
    error = 0.0002
    capacity = 1000
    decay_time = 86400
    ticker = MagicMock(NoOpTicker)
    data_path = '/foo/bar/baz'
    error_tightening_ratio = 0.4
    growth_factor = 3
    min_fill_factor = 0.1
    max_fill_factor = 0.9
    insert_tail = False
    disable_optimizations = True

    timing_bloom = MagicMock(TimingBloomFilter)
    timing_bloom.seconds_per_tick = 100
    blooms = [timing_bloom]

    # Create the bloom
    bloom = ScalingTimingBloomFilter(
        error=error,
        capacity=capacity,
        decay_time=decay_time,
        ticker=ticker,
        data_path=data_path,
        error_tightening_ratio=error_tightening_ratio,
        growth_factor=growth_factor,
        min_fill_factor=min_fill_factor,
        max_fill_factor=max_fill_factor,
        insert_tail=insert_tail,
        blooms=blooms,
        disable_optimizations=disable_optimizations,
    )

    # Check that the bloom's state matches expectations
    assert_bloom_values(
        bloom, {
            'error': error,
            'capacity': capacity,
            'decay_time': decay_time,
            'error_tightening_ratio': error_tightening_ratio,
            'growth_factor': growth_factor,
            'max_fill_factor': max_fill_factor,
            'min_fill_factor': min_fill_factor,
            'insert_tail': insert_tail,
            'data_path': data_path,
            'blooms': blooms,
            'error_initial': 0.00012,
            'seconds_per_tick': timing_bloom.seconds_per_tick,
            'disable_optimizations': disable_optimizations,
        })

    data_path, meta_filename, blooms_path = _get_paths(bloom.data_path, None)
    assert meta_filename == '/foo/bar/baz/meta.json'
    assert blooms_path == '/foo/bar/baz/blooms'

    ticker.setup.assert_called_once_with(bloom.decay,
                                         timing_bloom.seconds_per_tick)
    ticker.start.assert_called_once_with()
def get_bloom(n=100, **updates):
    kwargs = copy(BLOOM_DEFAULTS)
    kwargs.update(updates)

    # Create a bloom
    bloom = ScalingTimingBloomFilter(**kwargs)

    # Add a bunch of keys
    for i in range(100):
        bloom.add(str(i))

    # Check that the bloom is working as expected
    assert bloom.contains('1')
    assert bloom.contains(str(n // 2))
    assert not bloom.contains(str(n + 1))

    return bloom
def test_init_without_optimizations(timing_bloom_mock):
    # Setup test data
    error = 0.0002
    capacity = 1000
    decay_time = 86400
    disable_optimizations = True

    # Create bloom
    bloom = ScalingTimingBloomFilter(
        error=error,
        capacity=capacity,
        decay_time=decay_time,
        disable_optimizations=disable_optimizations,
    )

    assert_bloom_values(
        bloom, {
            'error': error,
            'capacity': capacity,
            'decay_time': decay_time,
            'error_tightening_ratio': 0.5,
            'error_initial': 0.0001,
            'growth_factor': 2,
            'max_fill_factor': 0.8,
            'min_fill_factor': 0.2,
            'insert_tail': True,
            'data_path': None,
            'seconds_per_tick': bloom.blooms[0].seconds_per_tick,
            'disable_optimizations': disable_optimizations,
        })

    expected_blooms_len = 1
    assert expected_blooms_len == len(bloom.blooms)

    timing_bloom_mock.assert_called_once_with(
        capacity=693,
        decay_time=decay_time,
        error=0.0001,
        id=0,
        disable_optimizations=disable_optimizations,
    )

    expected_ticker_class = NoOpTicker
    assert isinstance(bloom.ticker, expected_ticker_class)
def get_bloom(bloom_mocks=None, **overrides):
    '''
    Helper function to easily get a bloom for testing.
    '''
    kwargs = copy(BLOOM_DEFAULTS)
    kwargs.update(overrides)

    if bloom_mocks:
        blooms = []
        for mock_info in bloom_mocks:
            mock = MagicMock(TimingBloomFilter)
            mock_attrs = copy(TIMING_BLOOM_DEFAULTS)
            mock_attrs.update(mock_info.get('attrs', {}))
            for key, value in mock_attrs.iteritems():
                setattr(mock, key, value)

            for key, value in mock_info.get('return_values', {}).iteritems():
                attr = getattr(mock, key)
                attr.return_value = value

            blooms.append(mock)
        kwargs['blooms'] = blooms

    return ScalingTimingBloomFilter(**kwargs)