3

I am using rspec/capybara/VCR to record tapes. Currently my tapes are automatically named to include a simplified version of the hierarchy of the test that is being run, as is the default.

I would like to configure the cassette naming scheme so that it is dependent instead on the parameters of the request, so any PUT to /abc.com with a body of XYZ would use the same tape. My thought was to configure VCR with this:

config.around_http_request do |request|
  tape_name = Digest::SHA1.hexdigest [request.method, request.uri, request.headers.to_s, request.body.to_s].join('')
  puts "Using tape #{tape_name}"
  puts "on = #{VCR.turned_on?}"
  VCR.use_cassette(tape_name, :record => :new_episodes, &request)
end

But when I do that, eventually I get the errors such as:

There is already a cassette with the same name (5d971f35322c4e0cf7d379aa39a28ef12994552f).  You cannot nest multiple cassettes with the same name.

How can I name tapes with what they contain and prevent this error?

Deepak Mahakale
  • 22,834
  • 10
  • 68
  • 88
Eric
  • 5,815
  • 3
  • 25
  • 34
  • 2
    It looks like it's called twice with the exact same `[request.method, request.uri, request.headers.to_s, request.body.to_s]`. – Eric Duminil Jan 29 '17 at 13:47
  • Please explain, I don't understand what you mean. – Eric Jan 29 '17 at 14:33
  • If there's a cassette with the exat same name "5d971f35322c4e0cf7d379aa39a28ef12994552f", it means that this hash has already been calculated. A collision is very unlikely, so a previous call with the exact same `request` must have been done. – Eric Duminil Jan 29 '17 at 14:38
  • 2
    Right but in that case, shouldn't it be using that tape rather than trying to make a new one? – Eric Jan 29 '17 at 15:52
  • Sorry, I've never used VCR. – Eric Duminil Jan 29 '17 at 16:03

1 Answers1

2

I've just experienced the same problem and it seems that the root cause was that cassettes somehow got nested during some requests (i.e. like using a VCR.use_cassette('whatever') inside another VCR.use_cassette('whatever') block). So, I tried to put an eject_cassette prior to use_cassette and it seems to work fine, e.g. in this case:

VCR.eject_cassette(tape_name)
VCR.use_cassette(tape_name, :record => :new_episodes, &request)
alexb
  • 880
  • 11
  • 16