googleapis / google-api-ruby-client

REST client for Google APIs
Apache License 2.0
2.81k stars 871 forks source link

Compatibility for VCR in tests #356

Closed fotinakis closed 8 years ago

fotinakis commented 8 years ago

Just an FYI issue, not sure what the best solution is here. I think this is a bad interaction between WebMock and google-api-client.

I use VCR and WebMock underneath to record and replay all interactions with Google APIs in tests. Ever since upgrading from google-api-client 0.9.pre3 to 0.9.1 all of my integration tests would break with:

     MultiJson::ParseError:
       JSON::ParserError
     # ./vendor/bundle/ruby/2.2.0/gems/multi_json-1.11.2/lib/multi_json/adapter.rb:19:in `load'
     # ./vendor/bundle/ruby/2.2.0/gems/multi_json-1.11.2/lib/multi_json.rb:119:in `load'
     # ./vendor/bundle/ruby/2.2.0/gems/representable-2.3.0/lib/representable/json.rb:34:in `from_json'
     # ./vendor/bundle/ruby/2.2.0/gems/google-api-client-0.9.2/lib/google/apis/core/api_command.rb:74:in `decode_response_body'
     # ./vendor/bundle/ruby/2.2.0/gems/google-api-client-0.9.2/lib/google/apis/core/http_command.rb:171:in `process_response'
     # ./vendor/bundle/ruby/2.2.0/gems/google-api-client-0.9.2/lib/google/apis/core/upload.rb:198:in `process_response'
     # ./vendor/bundle/ruby/2.2.0/gems/google-api-client-0.9.2/lib/google/apis/core/upload.rb:275:in `execute_once'
     # ./vendor/bundle/ruby/2.2.0/gems/google-api-client-0.9.2/lib/google/apis/core/http_command.rb:107:in `block (2 levels) in execute'
     # ./vendor/bundle/ruby/2.2.0/gems/retriable-2.1.0/lib/retriable.rb:54:in `block in retriable'
     # ./vendor/bundle/ruby/2.2.0/gems/retriable-2.1.0/lib/retriable.rb:48:in `times'
     # ./vendor/bundle/ruby/2.2.0/gems/retriable-2.1.0/lib/retriable.rb:48:in `retriable'
     # ./vendor/bundle/ruby/2.2.0/gems/google-api-client-0.9.2/lib/google/apis/core/http_command.rb:104:in `block in execute'
     # ./vendor/bundle/ruby/2.2.0/gems/retriable-2.1.0/lib/retriable.rb:54:in `block in retriable'
     # ./vendor/bundle/ruby/2.2.0/gems/retriable-2.1.0/lib/retriable.rb:48:in `times'
     # ./vendor/bundle/ruby/2.2.0/gems/retriable-2.1.0/lib/retriable.rb:48:in `retriable'
     # ./vendor/bundle/ruby/2.2.0/gems/google-api-client-0.9.2/lib/google/apis/core/http_command.rb:96:in `execute'
     # ./vendor/bundle/ruby/2.2.0/gems/google-api-client-0.9.2/lib/google/apis/core/base_service.rb:267:in `execute_or_queue_command'
     # ./vendor/bundle/ruby/2.2.0/gems/google-api-client-0.9.2/generated/google/apis/storage_v1/service.rb:1511:in `insert_object'

It turns out that JSON::ParserError is raised when given a blank string to decode. After digging in, sure enough all of my VCR cassette files had recorded responses with empty response body (even though Content-Length would still be correct).

I dug through your spec_helper and found the monkey-patch for WebMock to support chunked responses—I thought that was it, but it turns out that I didn't need that, I only needed to add:

require 'google/apis/core/base_service'
Google::Apis::ClientOptions.default.use_net_http = true

With that in my spec_helper.rb, everything works again because my cassettes record full response bodies again.

I assume that this is a bad interaction between WebMock, VCR, and google-api-client, but I haven't narrowed it to the smallest case yet (and probably won't now that I have a fix). For reference, here are a few of my related config settings:

I run this in my RSpec.configure block in spec_helper:

WebMock.disable_net_connect!

And my VCR setup is (slightly trimmed):

VCR.configure do |c|
  c.configure_rspec_metadata!
  c.cassette_library_dir = 'spec/cassettes'
  c.hook_into :webmock
  c.ignore_localhost = true

  # If an HTTP call returns blob contents, don't convert it to ASCII for the JSON file.
  c.preserve_exact_body_bytes do |http_message|
    http_message.body.encoding.name == 'ASCII-8BIT' ||
      !http_message.body.valid_encoding?
  end
end

Thanks!

sqrrrl commented 8 years ago

See #336 which has some related info.

fotinakis commented 8 years ago

Great, thanks! Looks like https://github.com/bblimke/webmock/pull/582 will fix this issue in the next WebMock release.

fotinakis commented 8 years ago

The newly released WebMock 1.23.0 fixes this issue. I've upgraded and deleted the spec_helper fix noted above, things work great by default.