warden-protocol 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. data/.gitignore +17 -0
  2. data/.rspec +1 -0
  3. data/CHANGELOG.md +14 -0
  4. data/Gemfile +6 -0
  5. data/README.md +13 -0
  6. data/Rakefile +40 -0
  7. data/lib/warden/protocol.rb +4 -0
  8. data/lib/warden/protocol/base.rb +168 -0
  9. data/lib/warden/protocol/buffer.rb +69 -0
  10. data/lib/warden/protocol/build.sh +13 -0
  11. data/lib/warden/protocol/message.rb +50 -0
  12. data/lib/warden/protocol/pb.rb +497 -0
  13. data/lib/warden/protocol/pb/copy_in.proto +35 -0
  14. data/lib/warden/protocol/pb/copy_out.proto +39 -0
  15. data/lib/warden/protocol/pb/create.proto +65 -0
  16. data/lib/warden/protocol/pb/destroy.proto +33 -0
  17. data/lib/warden/protocol/pb/echo.proto +26 -0
  18. data/lib/warden/protocol/pb/error.proto +19 -0
  19. data/lib/warden/protocol/pb/info.proto +95 -0
  20. data/lib/warden/protocol/pb/limit_bandwidth.proto +30 -0
  21. data/lib/warden/protocol/pb/limit_disk.proto +70 -0
  22. data/lib/warden/protocol/pb/limit_memory.proto +34 -0
  23. data/lib/warden/protocol/pb/link.proto +40 -0
  24. data/lib/warden/protocol/pb/list.proto +25 -0
  25. data/lib/warden/protocol/pb/message.proto +36 -0
  26. data/lib/warden/protocol/pb/net_in.proto +39 -0
  27. data/lib/warden/protocol/pb/net_out.proto +35 -0
  28. data/lib/warden/protocol/pb/ping.proto +24 -0
  29. data/lib/warden/protocol/pb/resource_limits.proto +30 -0
  30. data/lib/warden/protocol/pb/run.proto +29 -0
  31. data/lib/warden/protocol/pb/spawn.proto +37 -0
  32. data/lib/warden/protocol/pb/stop.proto +40 -0
  33. data/lib/warden/protocol/pb/stream.proto +41 -0
  34. data/lib/warden/protocol/version.rb +7 -0
  35. data/spec/base_spec.rb +150 -0
  36. data/spec/buffer_spec.rb +65 -0
  37. data/spec/copy_in_spec.rb +51 -0
  38. data/spec/copy_out_spec.rb +56 -0
  39. data/spec/create_spec.rb +70 -0
  40. data/spec/destroy_spec.rb +36 -0
  41. data/spec/echo_spec.rb +42 -0
  42. data/spec/error_spec.rb +33 -0
  43. data/spec/info_spec.rb +122 -0
  44. data/spec/limit_bandwidth_spec.rb +57 -0
  45. data/spec/limit_disk_spec.rb +103 -0
  46. data/spec/limit_memory_spec.rb +47 -0
  47. data/spec/link_spec.rb +67 -0
  48. data/spec/list_spec.rb +41 -0
  49. data/spec/net_in_spec.rb +57 -0
  50. data/spec/net_out_spec.rb +47 -0
  51. data/spec/ping_spec.rb +32 -0
  52. data/spec/resource_limits_spec.rb +84 -0
  53. data/spec/run_spec.rb +79 -0
  54. data/spec/spawn_spec.rb +55 -0
  55. data/spec/spec_helper.rb +11 -0
  56. data/spec/stop_spec.rb +46 -0
  57. data/spec/stream_spec.rb +65 -0
  58. data/spec/support/examples/wrappable_reply.rb +26 -0
  59. data/spec/support/examples/wrappable_request.rb +26 -0
  60. data/spec/support/helper.rb +122 -0
  61. data/spec/support/matchers.rb +22 -0
  62. data/warden-protocol.gemspec +21 -0
  63. metadata +166 -0
@@ -0,0 +1,84 @@
1
+ # coding: UTF-8
2
+
3
+ require "spec_helper"
4
+
5
+ describe Warden::Protocol::ResourceLimits do
6
+ subject do
7
+ described_class.new
8
+ end
9
+
10
+ field :as do
11
+ it_should_be_optional
12
+ it_should_be_typed_as_uint64
13
+ end
14
+
15
+ field :core do
16
+ it_should_be_optional
17
+ it_should_be_typed_as_uint64
18
+ end
19
+
20
+ field :cpu do
21
+ it_should_be_optional
22
+ it_should_be_typed_as_uint64
23
+ end
24
+
25
+ field :data do
26
+ it_should_be_optional
27
+ it_should_be_typed_as_uint64
28
+ end
29
+
30
+ field :fsize do
31
+ it_should_be_optional
32
+ it_should_be_typed_as_uint64
33
+ end
34
+
35
+ field :locks do
36
+ it_should_be_optional
37
+ it_should_be_typed_as_uint64
38
+ end
39
+
40
+ field :memlock do
41
+ it_should_be_optional
42
+ it_should_be_typed_as_uint64
43
+ end
44
+
45
+ field :msgqueue do
46
+ it_should_be_optional
47
+ it_should_be_typed_as_uint64
48
+ end
49
+
50
+ field :nice do
51
+ it_should_be_optional
52
+ it_should_be_typed_as_uint64
53
+ end
54
+
55
+ field :nofile do
56
+ it_should_be_optional
57
+ it_should_be_typed_as_uint64
58
+ end
59
+
60
+ field :nproc do
61
+ it_should_be_optional
62
+ it_should_be_typed_as_uint64
63
+ end
64
+
65
+ field :rss do
66
+ it_should_be_optional
67
+ it_should_be_typed_as_uint64
68
+ end
69
+
70
+ field :rtprio do
71
+ it_should_be_optional
72
+ it_should_be_typed_as_uint64
73
+ end
74
+
75
+ field :sigpending do
76
+ it_should_be_optional
77
+ it_should_be_typed_as_uint64
78
+ end
79
+
80
+ field :stack do
81
+ it_should_be_optional
82
+ it_should_be_typed_as_uint64
83
+ end
84
+ end
data/spec/run_spec.rb ADDED
@@ -0,0 +1,79 @@
1
+ # coding: UTF-8
2
+
3
+ require "spec_helper"
4
+
5
+ module Warden::Protocol
6
+ describe RunRequest do
7
+ subject(:request) do
8
+ described_class.new(:handle => "handle", :script => "echo foo")
9
+ end
10
+
11
+ it_should_behave_like "wrappable request"
12
+
13
+ its("class.type_camelized") { should == "Run" }
14
+ its("class.type_underscored") { should == "run" }
15
+
16
+ field :handle do
17
+ it_should_be_required
18
+ end
19
+
20
+ field :script do
21
+ it_should_be_required
22
+ end
23
+
24
+ field :privileged do
25
+ it_should_be_optional
26
+ it_should_default_to false
27
+ end
28
+
29
+ field :rlimits do
30
+ it_should_be_optional
31
+
32
+ it "should be populated with ResourceLimits object" do
33
+ request.rlimits = ResourceLimits.new
34
+ request.should be_valid
35
+ end
36
+ end
37
+
38
+ it "should respond to #create_response" do
39
+ request.create_response.should be_a(RunResponse)
40
+ end
41
+ end
42
+
43
+ describe RunResponse do
44
+ subject(:response) do
45
+ described_class.new
46
+ end
47
+
48
+ it_should_behave_like "wrappable response"
49
+
50
+ its("class.type_camelized") { should == "Run" }
51
+ its("class.type_underscored") { should == "run" }
52
+
53
+ it { should be_ok }
54
+ it { should_not be_error }
55
+
56
+ field :exit_status do
57
+ it_should_be_optional
58
+ it_should_be_typed_as_uint
59
+ end
60
+
61
+ field :stdout do
62
+ it_should_be_optional
63
+ it_should_be_typed_as_string
64
+ end
65
+
66
+ field :stderr do
67
+ it_should_be_optional
68
+ it_should_be_typed_as_string
69
+ end
70
+
71
+ field :info do
72
+ it_should_be_optional
73
+
74
+ it "should be a InfoResponse" do
75
+ field.type.should == InfoResponse
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,55 @@
1
+ # coding: UTF-8
2
+
3
+ require "spec_helper"
4
+
5
+ describe Warden::Protocol::SpawnRequest do
6
+ subject(:request) do
7
+ described_class.new(:handle => "handle", :script => "echo foo")
8
+ end
9
+
10
+ it_should_behave_like "wrappable request"
11
+
12
+ its("class.type_camelized") { should == "Spawn" }
13
+ its("class.type_underscored") { should == "spawn" }
14
+
15
+ field :handle do
16
+ it_should_be_required
17
+ end
18
+
19
+ field :script do
20
+ it_should_be_required
21
+ end
22
+
23
+ field :privileged do
24
+ it_should_be_optional
25
+ it_should_default_to false
26
+ end
27
+
28
+ it "should be populated with ResourceLimits object" do
29
+ request.rlimits = Warden::Protocol::ResourceLimits.new
30
+ request.should be_valid
31
+ end
32
+
33
+ it "should respond to #create_response" do
34
+ request.create_response.should be_a(Warden::Protocol::SpawnResponse)
35
+ end
36
+ end
37
+
38
+ describe Warden::Protocol::SpawnResponse do
39
+ subject(:response) do
40
+ described_class.new(:job_id => 1)
41
+ end
42
+
43
+ it_should_behave_like "wrappable response"
44
+
45
+ its("class.type_camelized") { should == "Spawn" }
46
+ its("class.type_underscored") { should == "spawn" }
47
+
48
+ it { should be_ok }
49
+ it { should_not be_error }
50
+
51
+ field :job_id do
52
+ it_should_be_required
53
+ it_should_be_typed_as_uint
54
+ end
55
+ end
@@ -0,0 +1,11 @@
1
+ # coding: UTF-8
2
+
3
+ require "rspec"
4
+ require "rspec/autorun"
5
+ require "warden/protocol"
6
+
7
+ Dir["./spec/support/**/*.rb"].each { |f| require f }
8
+
9
+ RSpec.configure do |config|
10
+ config.include(Helper)
11
+ end
data/spec/stop_spec.rb ADDED
@@ -0,0 +1,46 @@
1
+ # coding: UTF-8
2
+
3
+ require "spec_helper"
4
+
5
+ describe Warden::Protocol::StopRequest do
6
+ subject(:request) do
7
+ described_class.new(:handle => "handle")
8
+ end
9
+
10
+ it_should_behave_like "wrappable request"
11
+
12
+ its("class.type_camelized") { should == "Stop" }
13
+ its("class.type_underscored") { should == "stop" }
14
+
15
+ field :handle do
16
+ it_should_be_required
17
+ end
18
+
19
+ field :background do
20
+ it_should_be_optional
21
+ it_should_be_typed_as_boolean
22
+ end
23
+
24
+ field :kill do
25
+ it_should_be_optional
26
+ it_should_be_typed_as_boolean
27
+ end
28
+
29
+ it "should respond to #create_response" do
30
+ request.create_response.should be_a(Warden::Protocol::StopResponse)
31
+ end
32
+ end
33
+
34
+ describe Warden::Protocol::StopResponse do
35
+ subject(:response) do
36
+ described_class.new
37
+ end
38
+
39
+ it_should_behave_like "wrappable response"
40
+
41
+ its("class.type_camelized") { should == "Stop" }
42
+ its("class.type_underscored") { should == "stop" }
43
+
44
+ it { should be_ok }
45
+ it { should_not be_error }
46
+ end
@@ -0,0 +1,65 @@
1
+ # coding: UTF-8
2
+
3
+ require "spec_helper"
4
+
5
+ describe Warden::Protocol::StreamRequest do
6
+ subject(:request) do
7
+ described_class.new(:handle => "handle", :job_id => 1)
8
+ end
9
+
10
+ it_should_behave_like "wrappable request"
11
+
12
+ its("class.type_camelized") { should == "Stream" }
13
+ its("class.type_underscored") { should == "stream" }
14
+
15
+ field :handle do
16
+ it_should_be_required
17
+ it_should_be_typed_as_string
18
+ end
19
+
20
+ field :job_id do
21
+ it_should_be_required
22
+ it_should_be_typed_as_uint
23
+ end
24
+
25
+ it "should respond to #create_response" do
26
+ request.create_response.should be_a(Warden::Protocol::StreamResponse)
27
+ end
28
+ end
29
+
30
+ describe Warden::Protocol::StreamResponse do
31
+ subject(:response) do
32
+ described_class.new
33
+ end
34
+
35
+ it_should_behave_like "wrappable response"
36
+
37
+ its("class.type_camelized") { should == "Stream" }
38
+ its("class.type_underscored") { should == "stream" }
39
+
40
+ it { should be_ok }
41
+ it { should_not be_error }
42
+
43
+ field :name do
44
+ it_should_be_optional
45
+ it_should_be_typed_as_string
46
+ end
47
+
48
+ field :data do
49
+ it_should_be_optional
50
+ it_should_be_typed_as_string
51
+ end
52
+
53
+ field :exit_status do
54
+ it_should_be_optional
55
+ it_should_be_typed_as_uint
56
+ end
57
+
58
+ field :info do
59
+ it_should_be_optional
60
+
61
+ it "should be a InfoResponse" do
62
+ field.type.should == Warden::Protocol::InfoResponse
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,26 @@
1
+ # coding: UTF-8
2
+
3
+ shared_examples "wrappable response" do
4
+ let(:wrapped) { subject.wrap }
5
+
6
+ it "should respond to #wrap" do
7
+ wrapped.should be_a(Warden::Protocol::Message)
8
+
9
+ type_const = described_class.name.split("::").last.gsub(/Response$/, "")
10
+ wrapped.type.should == Warden::Protocol::Message::Type.const_get(type_const)
11
+ wrapped.payload.to_s.should == subject.encode.to_s
12
+ end
13
+
14
+ it "should retain class when unwrapped" do
15
+ wrapped.response.should be_a(described_class)
16
+ end
17
+
18
+ it "should retain properties when unwrapped" do
19
+ compare_without_encoding(wrapped.response.to_hash, subject.to_hash)
20
+ end
21
+
22
+ it "should retain properties when encoded and decoded" do
23
+ freshly_wrapped = Warden::Protocol::Message.decode(wrapped.encode.to_s)
24
+ compare_without_encoding(freshly_wrapped.response.to_hash, subject.to_hash)
25
+ end
26
+ end
@@ -0,0 +1,26 @@
1
+ # coding: UTF-8
2
+
3
+ shared_examples "wrappable request" do
4
+ let(:wrapped) { subject.wrap }
5
+
6
+ it "should respond to #wrap" do
7
+ wrapped.should be_a(Warden::Protocol::Message)
8
+
9
+ type_const = described_class.name.split("::").last.gsub(/Request$/, "")
10
+ wrapped.type.should == Warden::Protocol::Message::Type.const_get(type_const)
11
+ wrapped.payload.to_s.should == subject.encode.to_s
12
+ end
13
+
14
+ it "should retain class when unwrapped" do
15
+ wrapped.request.should be_a(described_class)
16
+ end
17
+
18
+ it "should retain properties when unwrapped" do
19
+ compare_without_encoding(wrapped.request.to_hash, subject.to_hash)
20
+ end
21
+
22
+ it "should retain properties when encoded and decoded" do
23
+ freshly_wrapped = Warden::Protocol::Message.decode(wrapped.encode.to_s)
24
+ compare_without_encoding(freshly_wrapped.request.to_hash, subject.to_hash)
25
+ end
26
+ end
@@ -0,0 +1,122 @@
1
+ # coding: UTF-8
2
+
3
+ module Helper
4
+ def self.included(base)
5
+ base.extend(ClassMethods)
6
+ end
7
+
8
+ # Compare strings in hashes regardless of their encoding
9
+ def compare_without_encoding(a, b)
10
+ (a.keys + b.keys).uniq.each do |key|
11
+ if a[key].respond_to?(:encoding)
12
+ a[key].should == b[key].force_encoding(a[key].encoding)
13
+ else
14
+ a[key].should == b[key]
15
+ end
16
+ end
17
+ end
18
+
19
+ module ClassMethods
20
+ def field(field, &blk)
21
+ describe field do
22
+ let(:field) do
23
+ subject.fields.values.detect { |f| f.name == field }
24
+ end
25
+
26
+ instance_eval(&blk)
27
+ end
28
+ end
29
+
30
+ def it_should_be_required
31
+ it "should be required" do
32
+ subject.should be_valid
33
+ subject.send("#{field.name}=", nil)
34
+ subject.should_not be_valid
35
+ end
36
+ end
37
+
38
+ def it_should_be_optional
39
+ it "should be optional" do
40
+ subject.should be_valid
41
+ subject.send("#{field.name}=", nil)
42
+ subject.should be_valid
43
+ end
44
+ end
45
+
46
+ def it_should_default_to(default)
47
+ it "should default to #{default}" do
48
+ instance = subject.reload
49
+ instance.send(field.name).should == default
50
+ end
51
+ end
52
+
53
+ def it_should_be_typed_as_uint
54
+ it "should not allow a signed integer" do
55
+ subject.send("#{field.name}=", -1)
56
+ subject.should_not be_valid
57
+ end
58
+
59
+ it "should allow zero" do
60
+ subject.send("#{field.name}=", 0)
61
+ subject.should be_valid
62
+ end
63
+
64
+ it "should allow integers larger than zero" do
65
+ subject.send("#{field.name}=", 37)
66
+ subject.should be_valid
67
+ end
68
+ end
69
+
70
+ def it_should_be_typed_as_uint32
71
+ it_should_be_typed_as_uint
72
+
73
+ it "should allow integer 2^32-1" do
74
+ subject.send("#{field.name}=", 2**32-1)
75
+ subject.should be_valid
76
+ end
77
+
78
+ it "should not allow integer 2^32" do
79
+ subject.send("#{field.name}=", 2**32)
80
+ subject.should_not be_valid
81
+ end
82
+ end
83
+
84
+ def it_should_be_typed_as_uint64
85
+ it_should_be_typed_as_uint
86
+
87
+ it "should allow integer 2^64-1" do
88
+ subject.send("#{field.name}=", 2**64-1)
89
+ subject.should be_valid
90
+ end
91
+
92
+ it "should not allow integer 2^64" do
93
+ subject.send("#{field.name}=", 2**64)
94
+ subject.should_not be_valid
95
+ end
96
+ end
97
+
98
+ def it_should_be_typed_as_string
99
+ it "should allow an empty string" do
100
+ subject.send("#{field.name}=", "")
101
+ subject.should be_valid
102
+ end
103
+
104
+ it "should allow a non-empty string" do
105
+ subject.send("#{field.name}=", "non-empty")
106
+ subject.should be_valid
107
+ end
108
+ end
109
+
110
+ def it_should_be_typed_as_boolean
111
+ it "should allow false" do
112
+ subject.send("#{field.name}=", false)
113
+ subject.should be_valid
114
+ end
115
+
116
+ it "should allow true" do
117
+ subject.send("#{field.name}=", true)
118
+ subject.should be_valid
119
+ end
120
+ end
121
+ end
122
+ end