func TestUpdateInvalidPeriod(t *testing.T) {
	clock := testutils.GetClock()
	tb := newTokenBucket(&rate{period: time.Second, average: 10, burst: 20}, clock)
	_, err := tb.consume(15)  
	require.NoError(t, err)
	err = tb.update(&rate{period: time.Second + 1, average: 30, burst: 40})  
	require.Error(t, err)
	clock.Sleep(500 * time.Millisecond)
	delay, err := tb.consume(11)
	require.NoError(t, err)
	assert.Equal(t, 100*time.Millisecond, delay)
	delay, err = tb.consume(10)
	require.NoError(t, err)
	assert.Equal(t, time.Duration(0), delay)
	clock.Sleep(40 * time.Second)
	_, err = tb.consume(21)
	require.Error(t, err)
	delay, err = tb.consume(20)
	require.NoError(t, err)
	assert.Equal(t, time.Duration(0), delay)
}
If a rate with different period is passed to the `update` method, then an
error is returned but the state of the bucket remains valid and unchanged.
package ratelimit
import (
	"testing"
	"time"
	"github.com/mailgun/timetools"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"github.com/vulcand/oxy/testutils"
)
func TestConsumeSingleToken(t *testing.T) {
	clock := testutils.GetClock()
	tb := newTokenBucket(&rate{period: time.Second, average: 1, burst: 1}, clock)
	delay, err := tb.consume(1)
	require.NoError(t, err)
	assert.Equal(t, time.Duration(0), delay)
	delay, err = tb.consume(1)
	require.NoError(t, err)
	assert.Equal(t, time.Second, delay)
	clock.Sleep(time.Second)
	delay, err = tb.consume(1)
	require.NoError(t, err)
	assert.Equal(t, time.Duration(0), delay)
	clock.Sleep(5 * time.Second)
	delay, err = tb.consume(1)
	require.NoError(t, err)
	assert.Equal(t, time.Duration(0), delay)
	delay, err = tb.consume(1)
	require.NoError(t, err)
	assert.Equal(t, time.Second, delay)
}
func TestFastConsumption(t *testing.T) {
	clock := testutils.GetClock()
	tb := newTokenBucket(&rate{period: time.Second, average: 1, burst: 1}, clock)
	delay, err := tb.consume(1)
	require.NoError(t, err)
	assert.Equal(t, time.Duration(0), delay)
	clock.Sleep(time.Millisecond * 200)
	delay, err = tb.consume(1)
	require.NoError(t, err)
	assert.Equal(t, time.Second, delay)
	clock.Sleep(time.Millisecond * 700)
	delay, err = tb.consume(1)
	require.NoError(t, err)
	assert.Equal(t, time.Second, delay)
	clock.Sleep(time.Millisecond * 100)
	delay, err = tb.consume(1)
	require.NoError(t, err)
	assert.Equal(t, time.Duration(0), delay)
}
func TestConsumeMultipleTokens(t *testing.T) {
	tb := newTokenBucket(&rate{period: time.Second, average: 3, burst: 5}, testutils.GetClock())
	delay, err := tb.consume(3)
	require.NoError(t, err)
	assert.Equal(t, time.Duration(0), delay)
	delay, err = tb.consume(2)
	require.NoError(t, err)
	assert.Equal(t, time.Duration(0), delay)
	delay, err = tb.consume(1)
	require.NoError(t, err)
	assert.NotEqual(t, time.Duration(0), delay)
}
func TestDelayIsCorrect(t *testing.T) {
	clock := testutils.GetClock()
	tb := newTokenBucket(&rate{period: time.Second, average: 3, burst: 5}, clock)
	delay, err := tb.consume(5)
	require.NoError(t, err)
	assert.Equal(t, time.Duration(0), delay)
	delay, err = tb.consume(3)
	require.NoError(t, err)
	assert.NotEqual(t, time.Duration(0), delay)
	clock.Sleep(delay)
	delay, err = tb.consume(3)
	require.NoError(t, err)
	assert.Equal(t, time.Duration(0), delay)
}
func TestExceedsBurst(t *testing.T) {
	tb := newTokenBucket(&rate{period: time.Second, average: 1, burst: 10}, testutils.GetClock())
	_, err := tb.consume(11)
	require.Error(t, err)
}
func TestConsumeBurst(t *testing.T) {
	tb := newTokenBucket(&rate{period: time.Second, average: 2, burst: 5}, testutils.GetClock())
	testutils.GetClock().Sleep(2 * time.Second)
	delay, err := tb.consume(5)
	require.NoError(t, err)
	assert.Equal(t, time.Duration(0), delay)
}
func TestConsumeEstimate(t *testing.T) {
	tb := newTokenBucket(&rate{period: time.Second, average: 2, burst: 4}, testutils.GetClock())
	delay, err := tb.consume(4)
	require.NoError(t, err)
	assert.Equal(t, time.Duration(0), delay)
	delay, err = tb.consume(4)
	require.NoError(t, err)
	assert.Equal(t, time.Duration(2)*time.Second, delay)
}