From 088769f82dfb1fcf0407c2c6974e4969cca9a146 Mon Sep 17 00:00:00 2001 From: Pieter Noordhuis Date: Tue, 26 Jun 2012 16:03:05 -0700 Subject: [PATCH] Create protocol definition gem Change-Id: Iacb8e43e1b0f7c399eb555e6ff45f5b0bd3aa2c5 --- warden-protocol/.gitignore | 17 +++ warden-protocol/Gemfile | 4 + warden-protocol/Rakefile | 9 ++ warden-protocol/lib/warden/protocol.rb | 29 +++++ warden-protocol/lib/warden/protocol/base.rb | 112 ++++++++++++++++++ .../lib/warden/protocol/copy_in.rb | 14 +++ .../lib/warden/protocol/copy_out.rb | 15 +++ warden-protocol/lib/warden/protocol/create.rb | 25 ++++ .../lib/warden/protocol/destroy.rb | 12 ++ warden-protocol/lib/warden/protocol/error.rb | 11 ++ warden-protocol/lib/warden/protocol/info.rb | 18 +++ .../lib/warden/protocol/limit_disk.rb | 16 +++ .../lib/warden/protocol/limit_memory.rb | 14 +++ warden-protocol/lib/warden/protocol/link.rb | 16 +++ warden-protocol/lib/warden/protocol/list.rb | 12 ++ warden-protocol/lib/warden/protocol/net_in.rb | 15 +++ .../lib/warden/protocol/net_out.rb | 14 +++ warden-protocol/lib/warden/protocol/ping.rb | 11 ++ warden-protocol/lib/warden/protocol/run.rb | 17 +++ warden-protocol/lib/warden/protocol/spawn.rb | 15 +++ warden-protocol/lib/warden/protocol/stop.rb | 12 ++ .../lib/warden/protocol/version.rb | 5 + warden-protocol/spec/base_spec.rb | 24 ++++ warden-protocol/spec/copy_in_spec.rb | 37 ++++++ warden-protocol/spec/copy_out_spec.rb | 42 +++++++ warden-protocol/spec/create_spec.rb | 41 +++++++ warden-protocol/spec/destroy_spec.rb | 22 ++++ warden-protocol/spec/error_spec.rb | 29 +++++ warden-protocol/spec/info_spec.rb | 51 ++++++++ warden-protocol/spec/limit_disk_spec.rb | 47 ++++++++ warden-protocol/spec/limit_memory_spec.rb | 37 ++++++ warden-protocol/spec/link_spec.rb | 47 ++++++++ warden-protocol/spec/list_spec.rb | 27 +++++ warden-protocol/spec/net_in_spec.rb | 42 +++++++ warden-protocol/spec/net_out_spec.rb | 33 ++++++ warden-protocol/spec/ping_spec.rb | 14 +++ warden-protocol/spec/run_spec.rb | 50 ++++++++ warden-protocol/spec/spawn_spec.rb | 40 +++++++ warden-protocol/spec/spec_helper.rb | 9 ++ warden-protocol/spec/stop_spec.rb | 22 ++++ .../spec/support/examples/wrappable_reply.rb | 19 +++ .../support/examples/wrappable_request.rb | 19 +++ warden-protocol/spec/support/helper.rb | 69 +++++++++++ warden-protocol/spec/support/matchers.rb | 20 ++++ warden-protocol/warden-protocol.gemspec | 21 ++++ 45 files changed, 1175 insertions(+) create mode 100644 warden-protocol/.gitignore create mode 100644 warden-protocol/Gemfile create mode 100644 warden-protocol/Rakefile create mode 100644 warden-protocol/lib/warden/protocol.rb create mode 100644 warden-protocol/lib/warden/protocol/base.rb create mode 100644 warden-protocol/lib/warden/protocol/copy_in.rb create mode 100644 warden-protocol/lib/warden/protocol/copy_out.rb create mode 100644 warden-protocol/lib/warden/protocol/create.rb create mode 100644 warden-protocol/lib/warden/protocol/destroy.rb create mode 100644 warden-protocol/lib/warden/protocol/error.rb create mode 100644 warden-protocol/lib/warden/protocol/info.rb create mode 100644 warden-protocol/lib/warden/protocol/limit_disk.rb create mode 100644 warden-protocol/lib/warden/protocol/limit_memory.rb create mode 100644 warden-protocol/lib/warden/protocol/link.rb create mode 100644 warden-protocol/lib/warden/protocol/list.rb create mode 100644 warden-protocol/lib/warden/protocol/net_in.rb create mode 100644 warden-protocol/lib/warden/protocol/net_out.rb create mode 100644 warden-protocol/lib/warden/protocol/ping.rb create mode 100644 warden-protocol/lib/warden/protocol/run.rb create mode 100644 warden-protocol/lib/warden/protocol/spawn.rb create mode 100644 warden-protocol/lib/warden/protocol/stop.rb create mode 100644 warden-protocol/lib/warden/protocol/version.rb create mode 100644 warden-protocol/spec/base_spec.rb create mode 100644 warden-protocol/spec/copy_in_spec.rb create mode 100644 warden-protocol/spec/copy_out_spec.rb create mode 100644 warden-protocol/spec/create_spec.rb create mode 100644 warden-protocol/spec/destroy_spec.rb create mode 100644 warden-protocol/spec/error_spec.rb create mode 100644 warden-protocol/spec/info_spec.rb create mode 100644 warden-protocol/spec/limit_disk_spec.rb create mode 100644 warden-protocol/spec/limit_memory_spec.rb create mode 100644 warden-protocol/spec/link_spec.rb create mode 100644 warden-protocol/spec/list_spec.rb create mode 100644 warden-protocol/spec/net_in_spec.rb create mode 100644 warden-protocol/spec/net_out_spec.rb create mode 100644 warden-protocol/spec/ping_spec.rb create mode 100644 warden-protocol/spec/run_spec.rb create mode 100644 warden-protocol/spec/spawn_spec.rb create mode 100644 warden-protocol/spec/spec_helper.rb create mode 100644 warden-protocol/spec/stop_spec.rb create mode 100644 warden-protocol/spec/support/examples/wrappable_reply.rb create mode 100644 warden-protocol/spec/support/examples/wrappable_request.rb create mode 100644 warden-protocol/spec/support/helper.rb create mode 100644 warden-protocol/spec/support/matchers.rb create mode 100644 warden-protocol/warden-protocol.gemspec diff --git a/warden-protocol/.gitignore b/warden-protocol/.gitignore new file mode 100644 index 00000000..d87d4be6 --- /dev/null +++ b/warden-protocol/.gitignore @@ -0,0 +1,17 @@ +*.gem +*.rbc +.bundle +.config +.yardoc +Gemfile.lock +InstalledFiles +_yardoc +coverage +doc/ +lib/bundler/man +pkg +rdoc +spec/reports +test/tmp +test/version_tmp +tmp diff --git a/warden-protocol/Gemfile b/warden-protocol/Gemfile new file mode 100644 index 00000000..e07ef1ed --- /dev/null +++ b/warden-protocol/Gemfile @@ -0,0 +1,4 @@ +source 'https://rubygems.org' + +# Specify your gem's dependencies in warden-protocol.gemspec +gemspec diff --git a/warden-protocol/Rakefile b/warden-protocol/Rakefile new file mode 100644 index 00000000..49ac5d0e --- /dev/null +++ b/warden-protocol/Rakefile @@ -0,0 +1,9 @@ +require "rspec/core/rake_task" +require "rspec/core/version" + +task :default => :spec + +desc "Run all examples" +RSpec::Core::RakeTask.new(:spec) do |t| + t.rspec_opts = %w[--color --format documentation] +end diff --git a/warden-protocol/lib/warden/protocol.rb b/warden-protocol/lib/warden/protocol.rb new file mode 100644 index 00000000..ec1d0d0d --- /dev/null +++ b/warden-protocol/lib/warden/protocol.rb @@ -0,0 +1,29 @@ +require "warden/protocol/version" + +require "warden/protocol/error" + +require "warden/protocol/create" +require "warden/protocol/stop" +require "warden/protocol/destroy" +require "warden/protocol/info" + +require "warden/protocol/spawn" +require "warden/protocol/link" +require "warden/protocol/run" + +require "warden/protocol/net_in" +require "warden/protocol/net_out" + +require "warden/protocol/copy_in" +require "warden/protocol/copy_out" + +require "warden/protocol/limit_memory" +require "warden/protocol/limit_disk" + +require "warden/protocol/ping" +require "warden/protocol/list" + +module Warden + module Protocol + end +end diff --git a/warden-protocol/lib/warden/protocol/base.rb b/warden-protocol/lib/warden/protocol/base.rb new file mode 100644 index 00000000..c2c990d6 --- /dev/null +++ b/warden-protocol/lib/warden/protocol/base.rb @@ -0,0 +1,112 @@ +require "beefcake" + +module Warden + module Protocol + module Type + Error = 1 + + Create = 11 + Stop = 12 + Destroy = 13 + Info = 14 + + Spawn = 21 + Link = 22 + Run = 23 + + NetIn = 31 + NetOut = 32 + + CopyIn = 41 + CopyOut = 42 + + LimitMemory = 51 + LimitDisk = 52 + + Ping = 91 + List = 92 + + def self.generate_klass_map(suffix) + map = Hash[self.constants.map do |name| + klass_name = "#{name}#{suffix}" + if Protocol.const_defined?(klass_name) + [const_get(name), Protocol.const_get(klass_name)] + end + end] + + if map.respond_to?(:default_proc=) + map.default_proc = lambda do |h, k| + raise "Unknown request type: #{k}" + end + end + + map + end + + def self.to_request_klass(type) + @request_klass_map ||= generate_klass_map("Request") + @request_klass_map[type] + end + + def self.to_response_klass(type) + @response_klass_map ||= generate_klass_map("Response") + @response_klass_map[type] + end + end + + class BaseMessage + include Beefcake::Message + + def reload + self.class.decode(encode) + end + end + + class BaseRequest < BaseMessage + def create_response(attributes = {}) + klass_name = self.class.name.gsub(/Request$/, "Response") + klass_name = klass_name.split("::").last + klass = Protocol.const_get(klass_name) + klass.new(attributes) + end + + def wrap + klass_name = self.class.name.gsub(/Request$/, "") + klass_name = klass_name.split("::").last + + WrappedRequest.new \ + :type => Type.const_get(klass_name), + :payload => encode + end + end + + class BaseResponse < BaseMessage + def wrap + klass_name = self.class.name.gsub(/Response$/, "") + klass_name = klass_name.split("::").last + + WrappedResponse.new \ + :type => Type.const_get(klass_name), + :payload => encode + end + end + + class WrappedRequest < BaseRequest + required :type, Type, 1 + required :payload, :string, 2 + + def request + Type.to_request_klass(type).decode(payload) + end + end + + class WrappedResponse < BaseResponse + required :type, Type, 1 + required :payload, :string, 2 + + def response + Type.to_response_klass(type).decode(payload) + end + end + end +end diff --git a/warden-protocol/lib/warden/protocol/copy_in.rb b/warden-protocol/lib/warden/protocol/copy_in.rb new file mode 100644 index 00000000..876cd4d9 --- /dev/null +++ b/warden-protocol/lib/warden/protocol/copy_in.rb @@ -0,0 +1,14 @@ +require "warden/protocol/base" + +module Warden + module Protocol + class CopyInRequest < BaseRequest + required :handle, :string, 1 + required :src_path, :string, 2 + required :dst_path, :string, 3 + end + + class CopyInResponse < BaseResponse + end + end +end diff --git a/warden-protocol/lib/warden/protocol/copy_out.rb b/warden-protocol/lib/warden/protocol/copy_out.rb new file mode 100644 index 00000000..3470574d --- /dev/null +++ b/warden-protocol/lib/warden/protocol/copy_out.rb @@ -0,0 +1,15 @@ +require "warden/protocol/base" + +module Warden + module Protocol + class CopyOutRequest < BaseRequest + required :handle, :string, 1 + required :src_path, :string, 2 + required :dst_path, :string, 3 + optional :owner, :string, 4 + end + + class CopyOutResponse < BaseResponse + end + end +end diff --git a/warden-protocol/lib/warden/protocol/create.rb b/warden-protocol/lib/warden/protocol/create.rb new file mode 100644 index 00000000..fe484659 --- /dev/null +++ b/warden-protocol/lib/warden/protocol/create.rb @@ -0,0 +1,25 @@ +require "warden/protocol/base" + +module Warden + module Protocol + class CreateRequest < BaseRequest + class BindMount < BaseMessage + module Mode + RO = 0 + RW = 1 + end + + required :src, :string, 1 + required :dst, :string, 2 + required :mode, BindMount::Mode, 3 + end + + repeated :bind_mounts, BindMount, 1 + optional :grace_time, :uint32, 2 + end + + class CreateResponse < BaseResponse + required :handle, :string, 1 + end + end +end diff --git a/warden-protocol/lib/warden/protocol/destroy.rb b/warden-protocol/lib/warden/protocol/destroy.rb new file mode 100644 index 00000000..5e55d2af --- /dev/null +++ b/warden-protocol/lib/warden/protocol/destroy.rb @@ -0,0 +1,12 @@ +require "warden/protocol/base" + +module Warden + module Protocol + class DestroyRequest < BaseRequest + required :handle, :string, 1 + end + + class DestroyResponse < BaseResponse + end + end +end diff --git a/warden-protocol/lib/warden/protocol/error.rb b/warden-protocol/lib/warden/protocol/error.rb new file mode 100644 index 00000000..eb42794a --- /dev/null +++ b/warden-protocol/lib/warden/protocol/error.rb @@ -0,0 +1,11 @@ +require "warden/protocol/base" + +module Warden + module Protocol + class ErrorResponse < BaseResponse + optional :message, :string, 2 + optional :data, :string, 4 + repeated :backtrace, :string, 3 + end + end +end diff --git a/warden-protocol/lib/warden/protocol/info.rb b/warden-protocol/lib/warden/protocol/info.rb new file mode 100644 index 00000000..be5e7b85 --- /dev/null +++ b/warden-protocol/lib/warden/protocol/info.rb @@ -0,0 +1,18 @@ +require "warden/protocol/base" + +module Warden + module Protocol + class InfoRequest < BaseRequest + required :handle, :string, 1 + end + + class InfoResponse < BaseResponse + optional :state, :string, 10 + + repeated :events, :string, 20 + + optional :host_ip, :string, 30 + optional :container_ip, :string, 31 + end + end +end diff --git a/warden-protocol/lib/warden/protocol/limit_disk.rb b/warden-protocol/lib/warden/protocol/limit_disk.rb new file mode 100644 index 00000000..4f2a0334 --- /dev/null +++ b/warden-protocol/lib/warden/protocol/limit_disk.rb @@ -0,0 +1,16 @@ +require "warden/protocol/base" + +module Warden + module Protocol + class LimitDiskRequest < BaseRequest + required :handle, :string, 1 + optional :block_limit, :uint32, 10 + optional :inode_limit, :uint32, 20 + end + + class LimitDiskResponse < BaseResponse + optional :block_limit, :uint32, 10 + optional :inode_limit, :uint32, 20 + end + end +end diff --git a/warden-protocol/lib/warden/protocol/limit_memory.rb b/warden-protocol/lib/warden/protocol/limit_memory.rb new file mode 100644 index 00000000..41551464 --- /dev/null +++ b/warden-protocol/lib/warden/protocol/limit_memory.rb @@ -0,0 +1,14 @@ +require "warden/protocol/base" + +module Warden + module Protocol + class LimitMemoryRequest < BaseRequest + required :handle, :string, 1 + optional :limit_in_bytes, :uint32, 2 + end + + class LimitMemoryResponse < BaseResponse + optional :limit_in_bytes, :uint32, 1 + end + end +end diff --git a/warden-protocol/lib/warden/protocol/link.rb b/warden-protocol/lib/warden/protocol/link.rb new file mode 100644 index 00000000..16f5b04d --- /dev/null +++ b/warden-protocol/lib/warden/protocol/link.rb @@ -0,0 +1,16 @@ +require "warden/protocol/base" + +module Warden + module Protocol + class LinkRequest < BaseRequest + required :handle, :string, 1 + required :job_id, :uint32, 2 + end + + class LinkResponse < BaseResponse + optional :exit_status, :uint32, 1 + optional :stdout, :string, 2 + optional :stderr, :string, 3 + end + end +end diff --git a/warden-protocol/lib/warden/protocol/list.rb b/warden-protocol/lib/warden/protocol/list.rb new file mode 100644 index 00000000..e5749ac4 --- /dev/null +++ b/warden-protocol/lib/warden/protocol/list.rb @@ -0,0 +1,12 @@ +require "warden/protocol/base" + +module Warden + module Protocol + class ListRequest < BaseRequest + end + + class ListResponse < BaseResponse + repeated :handles, :string, 1 + end + end +end diff --git a/warden-protocol/lib/warden/protocol/net_in.rb b/warden-protocol/lib/warden/protocol/net_in.rb new file mode 100644 index 00000000..96e9dbaf --- /dev/null +++ b/warden-protocol/lib/warden/protocol/net_in.rb @@ -0,0 +1,15 @@ +require "warden/protocol/base" + +module Warden + module Protocol + class NetInRequest < BaseRequest + required :handle, :string, 1 + optional :container_port, :uint32, 2 + end + + class NetInResponse < BaseResponse + required :host_port, :uint32, 1 + required :container_port, :uint32, 2 + end + end +end diff --git a/warden-protocol/lib/warden/protocol/net_out.rb b/warden-protocol/lib/warden/protocol/net_out.rb new file mode 100644 index 00000000..825a7c5d --- /dev/null +++ b/warden-protocol/lib/warden/protocol/net_out.rb @@ -0,0 +1,14 @@ +require "warden/protocol/base" + +module Warden + module Protocol + class NetOutRequest < BaseRequest + required :handle, :string, 1 + optional :network, :string, 2 + optional :port, :uint32, 3 + end + + class NetOutResponse < BaseResponse + end + end +end diff --git a/warden-protocol/lib/warden/protocol/ping.rb b/warden-protocol/lib/warden/protocol/ping.rb new file mode 100644 index 00000000..4e70a00b --- /dev/null +++ b/warden-protocol/lib/warden/protocol/ping.rb @@ -0,0 +1,11 @@ +require "warden/protocol/base" + +module Warden + module Protocol + class PingRequest < BaseRequest + end + + class PingResponse < BaseResponse + end + end +end diff --git a/warden-protocol/lib/warden/protocol/run.rb b/warden-protocol/lib/warden/protocol/run.rb new file mode 100644 index 00000000..1bbbf924 --- /dev/null +++ b/warden-protocol/lib/warden/protocol/run.rb @@ -0,0 +1,17 @@ +require "warden/protocol/base" + +module Warden + module Protocol + class RunRequest < BaseRequest + required :handle, :string, 1 + required :script, :string, 2 + optional :privileged, :bool, 3, :default => false + end + + class RunResponse < BaseResponse + optional :exit_status, :uint32, 1 + optional :stdout, :string, 2 + optional :stderr, :string, 3 + end + end +end diff --git a/warden-protocol/lib/warden/protocol/spawn.rb b/warden-protocol/lib/warden/protocol/spawn.rb new file mode 100644 index 00000000..39058ed8 --- /dev/null +++ b/warden-protocol/lib/warden/protocol/spawn.rb @@ -0,0 +1,15 @@ +require "warden/protocol/base" + +module Warden + module Protocol + class SpawnRequest < BaseRequest + required :handle, :string, 1 + required :script, :string, 2 + optional :privileged, :bool, 3, :default => false + end + + class SpawnResponse < BaseResponse + required :job_id, :uint32, 1 + end + end +end diff --git a/warden-protocol/lib/warden/protocol/stop.rb b/warden-protocol/lib/warden/protocol/stop.rb new file mode 100644 index 00000000..a4371909 --- /dev/null +++ b/warden-protocol/lib/warden/protocol/stop.rb @@ -0,0 +1,12 @@ +require "warden/protocol/base" + +module Warden + module Protocol + class StopRequest < BaseRequest + required :handle, :string, 1 + end + + class StopResponse < BaseResponse + end + end +end diff --git a/warden-protocol/lib/warden/protocol/version.rb b/warden-protocol/lib/warden/protocol/version.rb new file mode 100644 index 00000000..4aefcb61 --- /dev/null +++ b/warden-protocol/lib/warden/protocol/version.rb @@ -0,0 +1,5 @@ +module Warden + module Protocol + VERSION = "0.0.1" + end +end diff --git a/warden-protocol/spec/base_spec.rb b/warden-protocol/spec/base_spec.rb new file mode 100644 index 00000000..a9eb1b30 --- /dev/null +++ b/warden-protocol/spec/base_spec.rb @@ -0,0 +1,24 @@ +require "spec_helper" +require "warden/protocol" + +describe Warden::Protocol::WrappedRequest do + it "should respond to #request" do + w = Warden::Protocol::WrappedRequest.new + w.type = Warden::Protocol::Type::Ping + w.payload = Warden::Protocol::PingRequest.new.encode + w.should be_valid + + w.request.should be_a(Warden::Protocol::PingRequest) + end +end + +describe Warden::Protocol::WrappedResponse do + it "should respond to #response" do + w = Warden::Protocol::WrappedResponse.new + w.type = Warden::Protocol::Type::Ping + w.payload = Warden::Protocol::PingResponse.new.encode + w.should be_valid + + w.response.should be_a(Warden::Protocol::PingResponse) + end +end diff --git a/warden-protocol/spec/copy_in_spec.rb b/warden-protocol/spec/copy_in_spec.rb new file mode 100644 index 00000000..0bf83097 --- /dev/null +++ b/warden-protocol/spec/copy_in_spec.rb @@ -0,0 +1,37 @@ +require "spec_helper" +require "warden/protocol/copy_in" + +describe Warden::Protocol::CopyInRequest do + it_should_behave_like "wrappable request" + + subject do + described_class.new( + :handle => "handle", + :src_path => "/src", + :dst_path => "/dst", + ) + end + + field :handle do + it_should_be_required + it_should_be_typed_as_string + end + + field :src_path do + it_should_be_required + it_should_be_typed_as_string + end + + field :dst_path do + it_should_be_required + it_should_be_typed_as_string + end + + it "should respond to #create_response" do + subject.create_response.should be_a(Warden::Protocol::CopyInResponse) + end +end + +describe Warden::Protocol::CopyInResponse do + it_should_behave_like "wrappable response" +end diff --git a/warden-protocol/spec/copy_out_spec.rb b/warden-protocol/spec/copy_out_spec.rb new file mode 100644 index 00000000..9e9ade17 --- /dev/null +++ b/warden-protocol/spec/copy_out_spec.rb @@ -0,0 +1,42 @@ +require "spec_helper" +require "warden/protocol/copy_out" + +describe Warden::Protocol::CopyOutRequest do + it_should_behave_like "wrappable request" + + subject do + described_class.new( + :handle => "handle", + :src_path => "/src", + :dst_path => "/dst", + ) + end + + field :handle do + it_should_be_required + it_should_be_typed_as_string + end + + field :src_path do + it_should_be_required + it_should_be_typed_as_string + end + + field :dst_path do + it_should_be_required + it_should_be_typed_as_string + end + + field :owner do + it_should_be_optional + it_should_be_typed_as_string + end + + it "should respond to #create_response" do + subject.create_response.should be_a(Warden::Protocol::CopyOutResponse) + end +end + +describe Warden::Protocol::CopyOutResponse do + it_should_behave_like "wrappable response" +end diff --git a/warden-protocol/spec/create_spec.rb b/warden-protocol/spec/create_spec.rb new file mode 100644 index 00000000..d4721588 --- /dev/null +++ b/warden-protocol/spec/create_spec.rb @@ -0,0 +1,41 @@ +require "spec_helper" +require "warden/protocol/create" + +describe Warden::Protocol::CreateRequest do + it_should_behave_like "wrappable request" + + field :bind_mounts do + it_should_be_optional + + it "should be populated with BindMount objects" do + m = Warden::Protocol::CreateRequest::BindMount.new + m.src = "/src" + m.dst = "/dst" + m.mode = Warden::Protocol::CreateRequest::BindMount::Mode::RO + + subject.bind_mounts = [m] + subject.should be_valid + end + end + + field :grace_time do + it_should_be_optional + it_should_be_typed_as_uint + end + + it "should respond to #create_response" do + subject.create_response.should be_a(Warden::Protocol::CreateResponse) + end +end + +describe Warden::Protocol::CreateResponse do + it_should_behave_like "wrappable response" + + subject do + described_class.new(:handle => "handle") + end + + field :handle do + it_should_be_required + end +end diff --git a/warden-protocol/spec/destroy_spec.rb b/warden-protocol/spec/destroy_spec.rb new file mode 100644 index 00000000..273b3cfe --- /dev/null +++ b/warden-protocol/spec/destroy_spec.rb @@ -0,0 +1,22 @@ +require "spec_helper" +require "warden/protocol/destroy" + +describe Warden::Protocol::DestroyRequest do + it_should_behave_like "wrappable request" + + subject do + described_class.new(:handle => "handle") + end + + field :handle do + it_should_be_required + end + + it "should respond to #create_response" do + subject.create_response.should be_a(Warden::Protocol::DestroyResponse) + end +end + +describe Warden::Protocol::DestroyResponse do + it_should_behave_like "wrappable response" +end diff --git a/warden-protocol/spec/error_spec.rb b/warden-protocol/spec/error_spec.rb new file mode 100644 index 00000000..4dce6b47 --- /dev/null +++ b/warden-protocol/spec/error_spec.rb @@ -0,0 +1,29 @@ +require "spec_helper" +require "warden/protocol/error" + +describe Warden::Protocol::ErrorResponse do + it_should_behave_like "wrappable response" + + subject do + described_class.new + end + + field :message do + it_should_be_optional + it_should_be_typed_as_string + end + + field :data do + it_should_be_optional + it_should_be_typed_as_string + end + + field :backtrace do + it_should_be_optional + + it "should allow one or more entries" do + subject.backtrace = ["a", "b"] + subject.should be_valid + end + end +end diff --git a/warden-protocol/spec/info_spec.rb b/warden-protocol/spec/info_spec.rb new file mode 100644 index 00000000..a346d535 --- /dev/null +++ b/warden-protocol/spec/info_spec.rb @@ -0,0 +1,51 @@ +require "spec_helper" +require "warden/protocol/info" + +describe Warden::Protocol::InfoRequest do + it_should_behave_like "wrappable request" + + subject do + described_class.new(:handle => "handle") + end + + field :handle do + it_should_be_required + it_should_be_typed_as_string + end + + it "should respond to #create_response" do + subject.create_response.should be_a(Warden::Protocol::InfoResponse) + end +end + +describe Warden::Protocol::InfoResponse do + it_should_behave_like "wrappable response" + + subject do + described_class.new + end + + field :state do + it_should_be_optional + it_should_be_typed_as_string + end + + field :events do + it_should_be_optional + + it "should allow one or more events" do + subject.events = ["a", "b"] + subject.should be_valid + end + end + + field :host_ip do + it_should_be_optional + it_should_be_typed_as_string + end + + field :container_ip do + it_should_be_optional + it_should_be_typed_as_string + end +end diff --git a/warden-protocol/spec/limit_disk_spec.rb b/warden-protocol/spec/limit_disk_spec.rb new file mode 100644 index 00000000..aaf8ef2d --- /dev/null +++ b/warden-protocol/spec/limit_disk_spec.rb @@ -0,0 +1,47 @@ +require "spec_helper" +require "warden/protocol/limit_disk" + +describe Warden::Protocol::LimitDiskRequest do + it_should_behave_like "wrappable request" + + subject do + described_class.new(:handle => "handle") + end + + field :handle do + it_should_be_required + it_should_be_typed_as_string + end + + field :block_limit do + it_should_be_optional + it_should_be_typed_as_uint + end + + field :inode_limit do + it_should_be_optional + it_should_be_typed_as_uint + end + + it "should respond to #create_response" do + subject.create_response.should be_a(Warden::Protocol::LimitDiskResponse) + end +end + +describe Warden::Protocol::LimitDiskResponse do + it_should_behave_like "wrappable response" + + subject do + described_class.new + end + + field :block_limit do + it_should_be_optional + it_should_be_typed_as_uint + end + + field :inode_limit do + it_should_be_optional + it_should_be_typed_as_uint + end +end diff --git a/warden-protocol/spec/limit_memory_spec.rb b/warden-protocol/spec/limit_memory_spec.rb new file mode 100644 index 00000000..84f32a12 --- /dev/null +++ b/warden-protocol/spec/limit_memory_spec.rb @@ -0,0 +1,37 @@ +require "spec_helper" +require "warden/protocol/limit_memory" + +describe Warden::Protocol::LimitMemoryRequest do + it_should_behave_like "wrappable request" + + subject do + described_class.new(:handle => "handle") + end + + field :handle do + it_should_be_required + it_should_be_typed_as_string + end + + field :limit_in_bytes do + it_should_be_optional + it_should_be_typed_as_uint + end + + it "should respond to #create_response" do + subject.create_response.should be_a(Warden::Protocol::LimitMemoryResponse) + end +end + +describe Warden::Protocol::LimitMemoryResponse do + it_should_behave_like "wrappable response" + + subject do + described_class.new + end + + field :limit_in_bytes do + it_should_be_optional + it_should_be_typed_as_uint + end +end diff --git a/warden-protocol/spec/link_spec.rb b/warden-protocol/spec/link_spec.rb new file mode 100644 index 00000000..1b7a2000 --- /dev/null +++ b/warden-protocol/spec/link_spec.rb @@ -0,0 +1,47 @@ +require "spec_helper" +require "warden/protocol/link" + +describe Warden::Protocol::LinkRequest do + it_should_behave_like "wrappable request" + + subject do + described_class.new(:handle => "handle", :job_id => 1) + end + + field :handle do + it_should_be_required + it_should_be_typed_as_string + end + + field :job_id do + it_should_be_required + it_should_be_typed_as_uint + end + + it "should respond to #create_response" do + subject.create_response.should be_a(Warden::Protocol::LinkResponse) + end +end + +describe Warden::Protocol::LinkResponse do + it_should_behave_like "wrappable response" + + subject do + described_class.new + end + + field :exit_status do + it_should_be_optional + it_should_be_typed_as_uint + end + + field :stdout do + it_should_be_optional + it_should_be_typed_as_string + end + + field :stderr do + it_should_be_optional + it_should_be_typed_as_string + end +end diff --git a/warden-protocol/spec/list_spec.rb b/warden-protocol/spec/list_spec.rb new file mode 100644 index 00000000..7c90246e --- /dev/null +++ b/warden-protocol/spec/list_spec.rb @@ -0,0 +1,27 @@ +require "spec_helper" +require "warden/protocol/list" + +describe Warden::Protocol::ListRequest do + it_should_behave_like "wrappable request" + + it "should respond to #create_response" do + subject.create_response.should be_a(Warden::Protocol::ListResponse) + end +end + +describe Warden::Protocol::ListResponse do + it_should_behave_like "wrappable response" + + subject do + described_class.new + end + + field :handles do + it_should_be_optional + + it "should allow one or more handles" do + subject.handles = ["a", "b"] + subject.should be_valid + end + end +end diff --git a/warden-protocol/spec/net_in_spec.rb b/warden-protocol/spec/net_in_spec.rb new file mode 100644 index 00000000..3bcef649 --- /dev/null +++ b/warden-protocol/spec/net_in_spec.rb @@ -0,0 +1,42 @@ +require "spec_helper" +require "warden/protocol/net_in" + +describe Warden::Protocol::NetInRequest do + it_should_behave_like "wrappable request" + + subject do + described_class.new(:handle => "handle") + end + + field :handle do + it_should_be_required + it_should_be_typed_as_string + end + + field :container_port do + it_should_be_optional + it_should_be_typed_as_uint + end + + it "should respond to #create_response" do + subject.create_response.should be_a(Warden::Protocol::NetInResponse) + end +end + +describe Warden::Protocol::NetInResponse do + it_should_behave_like "wrappable response" + + subject do + described_class.new(:host_port => 1234, :container_port => 1234) + end + + field :host_port do + it_should_be_required + it_should_be_typed_as_uint + end + + field :container_port do + it_should_be_required + it_should_be_typed_as_uint + end +end diff --git a/warden-protocol/spec/net_out_spec.rb b/warden-protocol/spec/net_out_spec.rb new file mode 100644 index 00000000..234ddcb9 --- /dev/null +++ b/warden-protocol/spec/net_out_spec.rb @@ -0,0 +1,33 @@ +require "spec_helper" +require "warden/protocol/net_out" + +describe Warden::Protocol::NetOutRequest do + it_should_behave_like "wrappable request" + + subject do + described_class.new(:handle => "handle") + end + + field :handle do + it_should_be_required + it_should_be_typed_as_string + end + + field :network do + it_should_be_optional + it_should_be_typed_as_string + end + + field :port do + it_should_be_optional + it_should_be_typed_as_uint + end + + it "should respond to #create_response" do + subject.create_response.should be_a(Warden::Protocol::NetOutResponse) + end +end + +describe Warden::Protocol::NetOutResponse do + it_should_behave_like "wrappable response" +end diff --git a/warden-protocol/spec/ping_spec.rb b/warden-protocol/spec/ping_spec.rb new file mode 100644 index 00000000..f5213694 --- /dev/null +++ b/warden-protocol/spec/ping_spec.rb @@ -0,0 +1,14 @@ +require "spec_helper" +require "warden/protocol/ping" + +describe Warden::Protocol::PingRequest do + it_should_behave_like "wrappable request" + + it "should respond to #create_response" do + subject.create_response.should be_a(Warden::Protocol::PingResponse) + end +end + +describe Warden::Protocol::PingResponse do + it_should_behave_like "wrappable response" +end diff --git a/warden-protocol/spec/run_spec.rb b/warden-protocol/spec/run_spec.rb new file mode 100644 index 00000000..f17bd14a --- /dev/null +++ b/warden-protocol/spec/run_spec.rb @@ -0,0 +1,50 @@ +require "spec_helper" +require "warden/protocol/run" + +describe Warden::Protocol::RunRequest do + it_should_behave_like "wrappable request" + + subject do + described_class.new(:handle => "handle", :script => "echo foo") + end + + field :handle do + it_should_be_required + end + + field :script do + it_should_be_required + end + + field :privileged do + it_should_be_optional + it_should_default_to false + end + + it "should respond to #create_response" do + subject.create_response.should be_a(Warden::Protocol::RunResponse) + end +end + +describe Warden::Protocol::RunResponse do + it_should_behave_like "wrappable response" + + subject do + described_class.new + end + + field :exit_status do + it_should_be_optional + it_should_be_typed_as_uint + end + + field :stdout do + it_should_be_optional + it_should_be_typed_as_string + end + + field :stderr do + it_should_be_optional + it_should_be_typed_as_string + end +end diff --git a/warden-protocol/spec/spawn_spec.rb b/warden-protocol/spec/spawn_spec.rb new file mode 100644 index 00000000..1565ad97 --- /dev/null +++ b/warden-protocol/spec/spawn_spec.rb @@ -0,0 +1,40 @@ +require "spec_helper" +require "warden/protocol/spawn" + +describe Warden::Protocol::SpawnRequest do + it_should_behave_like "wrappable request" + + subject do + described_class.new(:handle => "handle", :script => "echo foo") + end + + field :handle do + it_should_be_required + end + + field :script do + it_should_be_required + end + + field :privileged do + it_should_be_optional + it_should_default_to false + end + + it "should respond to #create_response" do + subject.create_response.should be_a(Warden::Protocol::SpawnResponse) + end +end + +describe Warden::Protocol::SpawnResponse do + it_should_behave_like "wrappable response" + + subject do + described_class.new(:job_id => 1) + end + + field :job_id do + it_should_be_required + it_should_be_typed_as_uint + end +end diff --git a/warden-protocol/spec/spec_helper.rb b/warden-protocol/spec/spec_helper.rb new file mode 100644 index 00000000..6527fd79 --- /dev/null +++ b/warden-protocol/spec/spec_helper.rb @@ -0,0 +1,9 @@ +require "rspec" +require "rspec/autorun" +require "warden/protocol" + +Dir["./spec/support/**/*.rb"].each { |f| require f } + +RSpec.configure do |config| + config.include(Helper) +end diff --git a/warden-protocol/spec/stop_spec.rb b/warden-protocol/spec/stop_spec.rb new file mode 100644 index 00000000..5044cee6 --- /dev/null +++ b/warden-protocol/spec/stop_spec.rb @@ -0,0 +1,22 @@ +require "spec_helper" +require "warden/protocol/stop" + +describe Warden::Protocol::StopRequest do + it_should_behave_like "wrappable request" + + subject do + described_class.new(:handle => "handle") + end + + field :handle do + it_should_be_required + end + + it "should respond to #create_response" do + subject.create_response.should be_a(Warden::Protocol::StopResponse) + end +end + +describe Warden::Protocol::StopResponse do + it_should_behave_like "wrappable response" +end diff --git a/warden-protocol/spec/support/examples/wrappable_reply.rb b/warden-protocol/spec/support/examples/wrappable_reply.rb new file mode 100644 index 00000000..04827fd2 --- /dev/null +++ b/warden-protocol/spec/support/examples/wrappable_reply.rb @@ -0,0 +1,19 @@ +shared_examples "wrappable response" do + let(:wrapped) { subject.wrap } + + it "should respond to #wrap" do + wrapped.should be_a(Warden::Protocol::WrappedResponse) + + type_const = described_class.name.split("::").last.gsub(/Response$/, "") + wrapped.type.should == Warden::Protocol::Type.const_get(type_const) + wrapped.payload.to_s.should == subject.encode.to_s + end + + it "should retain class when unwrapped" do + wrapped.response.should be_a(described_class) + end + + it "should retain properties when unwrapped" do + wrapped.response.to_hash.should == subject.to_hash + end +end diff --git a/warden-protocol/spec/support/examples/wrappable_request.rb b/warden-protocol/spec/support/examples/wrappable_request.rb new file mode 100644 index 00000000..92866e4e --- /dev/null +++ b/warden-protocol/spec/support/examples/wrappable_request.rb @@ -0,0 +1,19 @@ +shared_examples "wrappable request" do + let(:wrapped) { subject.wrap } + + it "should respond to #wrap" do + wrapped.should be_a(Warden::Protocol::WrappedRequest) + + type_const = described_class.name.split("::").last.gsub(/Request$/, "") + wrapped.type.should == Warden::Protocol::Type.const_get(type_const) + wrapped.payload.to_s.should == subject.encode.to_s + end + + it "should retain class when unwrapped" do + wrapped.request.should be_a(described_class) + end + + it "should retain properties when unwrapped" do + wrapped.request.to_hash.should == subject.to_hash + end +end diff --git a/warden-protocol/spec/support/helper.rb b/warden-protocol/spec/support/helper.rb new file mode 100644 index 00000000..b2eaf83b --- /dev/null +++ b/warden-protocol/spec/support/helper.rb @@ -0,0 +1,69 @@ +module Helper + def self.included(base) + base.extend(ClassMethods) + end + + module ClassMethods + def field(field, &blk) + describe field do + let(:field) do + subject.fields.values.detect { |f| f.name == field } + end + + instance_eval(&blk) + end + end + + def it_should_be_required + it "should be required" do + subject.should be_valid + subject.send("#{field.name}=", nil) + subject.should_not be_valid + end + end + + def it_should_be_optional + it "should be optional" do + subject.should be_valid + subject.send("#{field.name}=", nil) + subject.should be_valid + end + end + + def it_should_default_to(default) + it "should default to #{default}" do + instance = subject.reload + instance.send(field.name).should == default + end + end + + def it_should_be_typed_as_uint + it "should not allow a signed integer" do + subject.send("#{field.name}=", -1) + subject.should_not be_valid + end + + it "should allow zero" do + subject.send("#{field.name}=", 0) + subject.should be_valid + end + + it "should allow integers larger than zero" do + subject.send("#{field.name}=", 37) + subject.should be_valid + end + end + + def it_should_be_typed_as_string + it "should allow an empty string" do + subject.send("#{field.name}=", "") + subject.should be_valid + end + + it "should allow a non-empty string" do + subject.send("#{field.name}=", "non-empty") + subject.should be_valid + end + end + end +end diff --git a/warden-protocol/spec/support/matchers.rb b/warden-protocol/spec/support/matchers.rb new file mode 100644 index 00000000..351335a2 --- /dev/null +++ b/warden-protocol/spec/support/matchers.rb @@ -0,0 +1,20 @@ +RSpec::Matchers.define :be_valid do + error = nil + + match do |actual| + begin + actual.class.decode(actual.encode) + rescue => error + end + + error == nil + end + + failure_message_for_should do |actual| + "expected #{actual} to be valid, but caught error: #{error}" + end + + failure_message_for_should_not do |actual| + "expected #{actual} not to be valid, but didn't catch an error" + end +end diff --git a/warden-protocol/warden-protocol.gemspec b/warden-protocol/warden-protocol.gemspec new file mode 100644 index 00000000..7c6c0e1b --- /dev/null +++ b/warden-protocol/warden-protocol.gemspec @@ -0,0 +1,21 @@ +# -*- encoding: utf-8 -*- +require File.expand_path('../lib/warden/protocol/version', __FILE__) + +Gem::Specification.new do |gem| + gem.authors = ["Pieter Noordhuis"] + gem.email = ["pcnoordhuis@gmail.com"] + gem.description = %q{Protocol specification for Warden} + gem.summary = %q{Protocol specification for Warden} + gem.homepage = "" + + gem.files = `git ls-files`.split($\) + gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) } + gem.test_files = gem.files.grep(%r{^(test|spec|features)/}) + gem.name = "warden-protocol" + gem.require_paths = ["lib"] + gem.version = Warden::Protocol::VERSION + + gem.add_dependency "beefcake" + + gem.add_development_dependency "rspec" +end