Sha256: 786f8adcf430a3c76d6fa767212da8807677919c89b932378e0ff7762e5984d9

Contents?: true

Size: 1.97 KB

Versions: 15

Compression:

Stored size: 1.97 KB

Contents

require 'helper'

require 'sidekiq'

describe Bearcat::RateLimiting do
  let!(:subject) { Bearcat::RateLimiting::RedisLimiter.new }
  let!(:client) { Bearcat::Client.new(prefix: "http://canvas.instructure.com", rate_limiter: subject, token: SecureRandom.hex) }
  let!(:token) { client.send(:rate_limit_key) }

  def fillup(count, rate: 100)
    count.times do
      subject.apply(token) do
        rate
      end
    end
  end

  it "fills the bucket with each request" do
    allow(Time).to receive(:now).and_return(Time.at(5000))
    expect(subject).to_not receive(:sleep)
    fillup(5)
    expect(subject.increment(token, 0, 0)).to eql({ count: 500.0, timestamp: 5000.0 })
  end

  it "drains the bucket over time" do
    allow(Time).to receive(:now).and_return(Time.at(5000))
    expect(subject).to_not receive(:sleep)
    fillup(5)

    allow(Time).to receive(:now).and_return(Time.at(5009))
    expect(subject.increment(token, 0, 0)).to eql({ count: 410.0, timestamp: 5009.0 })
  end

  it "sleeps requests when full" do
    allow(Time).to receive(:now).and_return(Time.at(5000))
    expect(subject).to receive(:sleep).at_least(:once)
    fillup(10)
  end

  it "rate limits requests" do
    allow(Time).to receive(:now).and_return(Time.at(5000))
    allow(subject).to receive(:sleep)
    fillup(10)

    stub_request(:get, /.*/).to_return(body: "{}")
    expect(subject).to receive(:sleep).once
    client.course(1)
  end

  it "retries after a Canvas 403 - Rate Limited" do
    stub_request(:get, /.*/).to_return(status: 403, body: "(Rate Limit Exceeded)")
    expect(subject).to receive(:apply).exactly(3).times.and_call_original
    expect(subject).to receive(:sleep).twice
    expect { client.course(1) }.to raise_error(Footrest::HttpError::Forbidden)
  end

  it "pushes x-rate-limit-remaining to the bucket" do
    stub_request(:get, /.*/).to_return(headers: { 'X-Rate-Limit-Remaining' => 120 }, body: "{}")
    expect(subject).to receive(:checkin_known).with(token, 20)
    client.course(1)
  end
end

Version data entries

15 entries across 15 versions & 1 rubygems

Version Path
bearcat-1.5.37 spec/bearcat/rate_limiting_spec.rb
bearcat-1.5.36 spec/bearcat/rate_limiting_spec.rb
bearcat-1.5.35 spec/bearcat/rate_limiting_spec.rb
bearcat-1.5.34 spec/bearcat/rate_limiting_spec.rb
bearcat-1.5.33 spec/bearcat/rate_limiting_spec.rb
bearcat-1.5.32 spec/bearcat/rate_limiting_spec.rb
bearcat-1.5.31 spec/bearcat/rate_limiting_spec.rb
bearcat-1.5.30 spec/bearcat/rate_limiting_spec.rb
bearcat-1.5.29 spec/bearcat/rate_limiting_spec.rb
bearcat-1.5.28 spec/bearcat/rate_limiting_spec.rb
bearcat-1.5.28.beta1 spec/bearcat/rate_limiting_spec.rb
bearcat-1.5.26 spec/bearcat/rate_limiting_spec.rb
bearcat-1.5.24 spec/bearcat/rate_limiting_spec.rb
bearcat-1.5.23 spec/bearcat/rate_limiting_spec.rb
bearcat-1.5.20 spec/bearcat/rate_limiting_spec.rb