Skip to content

Commit

Permalink
Add tests for SDSClient
Browse files Browse the repository at this point in the history
  So that we have faster feedback and confidence for future
modification.

  - Tests are added to cover both code paths
  - gemspec is modified to have a stricter requirement on
    em-http-request because our monkey patch depends specifically on
    1.0.0.beta3 (nothing newer than beta4!)
  - sinatra is added as a development dependency

Change-Id: I91e67462263baa5beb32272fa0d2141ce80a6d22
  • Loading branch information
d committed Oct 23, 2012
1 parent 4c0ae61 commit 3b11537
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 1 deletion.
4 changes: 4 additions & 0 deletions lib/services/api/multipart.rb
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,10 @@ def send_body(conn)

## Support to streaming the file when sending body
## TODO FIXME this patch whether depends on specified version???
## FIXME: yes it depends on a very specific beta version, yuck
## FIXME: a less gross alternative is to stream out the request body to disk,
## and use the :file option to instruct em-http-request to stream the body
## from disk
module EventMachine
class HttpClient
alias_method :original_send_request, :send_request
Expand Down
135 changes: 135 additions & 0 deletions spec/unit/sds_client_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
# Copyright (c) 2009-2012 VMware, Inc.

require "spec_helper"
require "tempfile"
require "timeout"
require "sinatra"

require "services/api/clients/sds_client"

describe VCAP::Services::Api::SDSClient do
describe "#import_from_data" do
it "issues a PUT to serialization data server" do
MockServer.stubbed_status = 200
MockServer.stubbed_body = "{\"url\": \"http://example.com/foo\"}"
port = VCAP::grab_ephemeral_port
server = Thin::Server.new("localhost", port, MockServer)
server.silent = true
t = Thread.new { server.start }

f = Tempfile.new("foo")
f.write("bar\n")
f.close

client = VCAP::Services::Api::SDSClient.new(
"http://localhost:#{port}",
"secret",
)
EM.error_handler do |e|
raise e
end
Timeout.timeout(0.5) do
sleep 0.02 until server.running?
end
server.should be_running

EM.next_tick do
fiber = Fiber.new do
client.import_from_data(
:service => "redis",
:service_id => "deadbeef",
:msg => f.path,
)
EM.stop
end
fiber.resume
end
Timeout.timeout(0.5) do
EM.reactor_thread.join
end
f.unlink
MockServer.last_request.forms["data_file"].should_not be_nil
MockServer.last_request.forms["data_file"][:tempfile].read.should == "bar\n"
MockServer.last_request.headers["HTTP_X_VCAP_SDS_UPLOAD_TOKEN"].should == "secret"
end

it "issues a PUT to serialization data server (without EM)" do
MockServer.stubbed_status = 200
MockServer.stubbed_body = "{\"url\": \"http://example.com/foo\"}"
server = nil
Thread.abort_on_exception = true
port = VCAP::grab_ephemeral_port
t = Thread.new do
Rack::Handler::WEBrick.run(MockServer,
:Port => port,
# shut up webrick
:Logger => WEBrick::Log.new(nil, WEBrick::Log::WARN),
:AccessLog => [],
) do |s|
server = s
end
end

f = Tempfile.new("foo")
f.write("bar\n")
f.close

client = VCAP::Services::Api::SDSClient.new(
"http://localhost:#{port}",
"secret",
2,
)
Timeout.timeout(0.5) do
sleep 0.02 until server && server.status == :Running
end
server.status.should == :Running

client.import_from_data(
:service => "redis",
:service_id => "deadbeef",
:msg => f.path,
)
# server#stop woul also do, but it takes 2 seconds...
server.shutdown
Timeout.timeout(0.5) do
t.join
end
server.status.should == :Stop
f.unlink
MockServer.last_request.forms["data_file"].should_not be_nil
MockServer.last_request.forms["data_file"][:tempfile].read.should == "bar\n"
MockServer.last_request.headers["HTTP_X_VCAP_SDS_UPLOAD_TOKEN"].should == "secret"
end
end
end

class MockServer < Sinatra::Base
RequestSignature = Struct.new(
:path,
:headers,
:forms,
)
class << self
@stubbed_status = 204
@stubbed_body = ""
attr_accessor :last_request, :stubbed_status, :stubbed_body
end

private
def record_signature(request)
r = RequestSignature.new
r.path = request.path
r.headers = request.env.select { |k,_| k.start_with?("HTTP_") }
r.forms = request.POST.dup
self.class.last_request = r
end

# FIXME: drop this when we switch to true PUT
enable :method_override

put "/*" do
record_signature(request)

[self.class.stubbed_status, self.class.stubbed_body]
end
end
3 changes: 2 additions & 1 deletion vcap_common.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ spec = Gem::Specification.new do |s|
s.add_dependency('posix-spawn', '~> 0.3.6')
s.add_dependency('membrane', '~> 0.0.2')
s.add_dependency('httpclient')
s.add_dependency('em-http-request', '~> 1.0.0.beta3')
s.add_dependency('em-http-request', '~> 1.0.0.beta3', '< 1.0.0.beta4')
s.add_dependency('multipart-post')
s.add_dependency('mime-types')
s.add_development_dependency('rake', '~> 0.9.2')
s.add_development_dependency('rspec')
s.add_development_dependency('sinatra')

s.require_paths = ['lib']

Expand Down

0 comments on commit 3b11537

Please sign in to comment.