warden-protocol 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
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