Trouble with S3, paperclip and VCR interaction #173

Closed
brycemcd opened this Issue Jun 4, 2012 · 4 comments

Projects

None yet

2 participants

@brycemcd

Also here: http://stackoverflow.com/questions/10825283/test-failure-when-using-vcr-with-paperclip

I'm getting a consistent error when testing a model which saves image data to S3. The first time I run the test, the code executes just fine. The second time I run the test, I get the errors documented below.

#vcr conf:
VCR.configure do |c|
  c.cassette_library_dir = 'spec/fixtures/cassettes'
  c.hook_into :webmock
end

Class, tests and backtrace: https://gist.github.com/2870882

@myronmarston
VCR member

Thanks, I'll look into this this week.

Is there a way you can pair the test down to something that's runnable in isolation (e.g. without the rest of your code base)? That would help me be able to troubleshoot this.

@myronmarston
VCR member

I took a bit of a look but nothing is jumping out as the obvious problem. I can look more into it if you give me a runnable example, but I've never used either aws-sdk or paperclip, so I don't have the time to come up with a debuggable example on my own.

@myronmarston
VCR member

OK, I've looked into this some more, and discovered the source of the bug. aws-sdk checks specifically to see if a response body is nil, and does something based on that.

When VCR records a response, it expects the response body to be a string, and winds up recording the response as an empty string. Semantically, HTTP doesn't have the concept of nil vs ''--it just has a zero-byte body, which can be validly represented in ruby as either nil or ''. Recording an empty string has never been a problem before, and allows me to treat the response body uniformly (e.g. I can assume it's a string, rather than needing unless body.nil? checks everywhere), but here, when it plays back, it keeps it as an empty string and thus the conditional logic in the aws-sdk gem that is triggered by having a nil body fails.

So...I'm not sure what to do about this yet. I'm thinking of changing VCR's recording so it doesn't normalize nil to an empty string. However, I'm not sure of all the repercussions of such a change yet--I have to think about it some more. Furthermore, it may actually be webmock that is normalizing it to an empty string, anyway, so the fix may have to be there.

Really, it'd be nice if aws-sdk wasn't so stringent about it's "empty body" checks...

@myronmarston myronmarston referenced this issue in myronmarston/webmock Jun 12, 2012
@myronmarston myronmarston Fix Net::HTTP adapter so that it returns `nil` for an empty body resp…
…onse.

This mirrors the real behavior of Net::HTTP and is the source of myronmarston/vcr#173.

A couple things to note:

- Rather than hitting an external URL (httpstat.us/204), this should probably
  hit the local webmock server; however, I can't figure out how to make the
  webmock server return a different response for different requests since it's
  writing directly to the socket w/o any request context available. Maybe it
  should be refactored to use rack or sinatra?
- I have no idea why, but Curb is returning a 400 Bad Request response for
  the request. Weird. Not sure why or how to fix it.
f7b3230
@myronmarston
VCR member

@brycem -- I just opened a WebMock pull request with a fix. Can you try locking your gemfile to that webmock rev and see if it fixes your problem? It fixed the problem for an isolated test I created.

@myronmarston myronmarston added a commit that closed this issue Jun 13, 2012
@myronmarston myronmarston Add spec for consistent handling of empty body responses.
The fix for this is dependent upon pull requests I've opened
with FakeWeb, WebMock and Faraday:

- chrisk/fakeweb#32
- bblimke/webmock#190
- https://github.com/technoweenie/faraday/pull/168

Closes #173.
b5b1350
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment