right_agent 2.0.7-x86-mingw32

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 (176) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +82 -0
  3. data/Rakefile +113 -0
  4. data/lib/right_agent.rb +59 -0
  5. data/lib/right_agent/actor.rb +182 -0
  6. data/lib/right_agent/actor_registry.rb +76 -0
  7. data/lib/right_agent/actors/agent_manager.rb +232 -0
  8. data/lib/right_agent/agent.rb +1149 -0
  9. data/lib/right_agent/agent_config.rb +480 -0
  10. data/lib/right_agent/agent_identity.rb +210 -0
  11. data/lib/right_agent/agent_tag_manager.rb +237 -0
  12. data/lib/right_agent/audit_formatter.rb +107 -0
  13. data/lib/right_agent/clients.rb +31 -0
  14. data/lib/right_agent/clients/api_client.rb +383 -0
  15. data/lib/right_agent/clients/auth_client.rb +247 -0
  16. data/lib/right_agent/clients/balanced_http_client.rb +369 -0
  17. data/lib/right_agent/clients/base_retry_client.rb +495 -0
  18. data/lib/right_agent/clients/right_http_client.rb +279 -0
  19. data/lib/right_agent/clients/router_client.rb +493 -0
  20. data/lib/right_agent/command.rb +30 -0
  21. data/lib/right_agent/command/agent_manager_commands.rb +150 -0
  22. data/lib/right_agent/command/command_client.rb +136 -0
  23. data/lib/right_agent/command/command_constants.rb +33 -0
  24. data/lib/right_agent/command/command_io.rb +126 -0
  25. data/lib/right_agent/command/command_parser.rb +87 -0
  26. data/lib/right_agent/command/command_runner.rb +118 -0
  27. data/lib/right_agent/command/command_serializer.rb +63 -0
  28. data/lib/right_agent/connectivity_checker.rb +179 -0
  29. data/lib/right_agent/console.rb +65 -0
  30. data/lib/right_agent/core_payload_types.rb +44 -0
  31. data/lib/right_agent/core_payload_types/cookbook.rb +61 -0
  32. data/lib/right_agent/core_payload_types/cookbook_position.rb +46 -0
  33. data/lib/right_agent/core_payload_types/cookbook_repository.rb +116 -0
  34. data/lib/right_agent/core_payload_types/cookbook_sequence.rb +70 -0
  35. data/lib/right_agent/core_payload_types/dev_repositories.rb +100 -0
  36. data/lib/right_agent/core_payload_types/dev_repository.rb +76 -0
  37. data/lib/right_agent/core_payload_types/event_categories.rb +38 -0
  38. data/lib/right_agent/core_payload_types/executable_bundle.rb +130 -0
  39. data/lib/right_agent/core_payload_types/login_policy.rb +72 -0
  40. data/lib/right_agent/core_payload_types/login_user.rb +79 -0
  41. data/lib/right_agent/core_payload_types/planned_volume.rb +94 -0
  42. data/lib/right_agent/core_payload_types/recipe_instantiation.rb +73 -0
  43. data/lib/right_agent/core_payload_types/repositories_bundle.rb +50 -0
  44. data/lib/right_agent/core_payload_types/right_script_attachment.rb +95 -0
  45. data/lib/right_agent/core_payload_types/right_script_instantiation.rb +94 -0
  46. data/lib/right_agent/core_payload_types/runlist_policy.rb +44 -0
  47. data/lib/right_agent/core_payload_types/secure_document.rb +66 -0
  48. data/lib/right_agent/core_payload_types/secure_document_location.rb +63 -0
  49. data/lib/right_agent/core_payload_types/software_repository_instantiation.rb +61 -0
  50. data/lib/right_agent/daemonize.rb +35 -0
  51. data/lib/right_agent/dispatched_cache.rb +109 -0
  52. data/lib/right_agent/dispatcher.rb +272 -0
  53. data/lib/right_agent/enrollment_result.rb +221 -0
  54. data/lib/right_agent/exceptions.rb +87 -0
  55. data/lib/right_agent/history.rb +145 -0
  56. data/lib/right_agent/log.rb +460 -0
  57. data/lib/right_agent/minimal.rb +46 -0
  58. data/lib/right_agent/monkey_patches.rb +30 -0
  59. data/lib/right_agent/monkey_patches/ruby_patch.rb +55 -0
  60. data/lib/right_agent/monkey_patches/ruby_patch/array_patch.rb +29 -0
  61. data/lib/right_agent/monkey_patches/ruby_patch/darwin_patch.rb +24 -0
  62. data/lib/right_agent/monkey_patches/ruby_patch/linux_patch.rb +24 -0
  63. data/lib/right_agent/monkey_patches/ruby_patch/linux_patch/file_patch.rb +30 -0
  64. data/lib/right_agent/monkey_patches/ruby_patch/object_patch.rb +49 -0
  65. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch.rb +32 -0
  66. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/file_patch.rb +60 -0
  67. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/process_patch.rb +63 -0
  68. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/stdio_patch.rb +27 -0
  69. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/time_patch.rb +55 -0
  70. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/win32ole_patch.rb +34 -0
  71. data/lib/right_agent/multiplexer.rb +102 -0
  72. data/lib/right_agent/offline_handler.rb +270 -0
  73. data/lib/right_agent/operation_result.rb +300 -0
  74. data/lib/right_agent/packets.rb +673 -0
  75. data/lib/right_agent/payload_formatter.rb +104 -0
  76. data/lib/right_agent/pending_requests.rb +128 -0
  77. data/lib/right_agent/pid_file.rb +159 -0
  78. data/lib/right_agent/platform.rb +770 -0
  79. data/lib/right_agent/platform/unix/darwin/platform.rb +102 -0
  80. data/lib/right_agent/platform/unix/linux/platform.rb +305 -0
  81. data/lib/right_agent/platform/unix/platform.rb +226 -0
  82. data/lib/right_agent/platform/windows/mingw/platform.rb +447 -0
  83. data/lib/right_agent/platform/windows/mswin/platform.rb +236 -0
  84. data/lib/right_agent/platform/windows/platform.rb +1808 -0
  85. data/lib/right_agent/protocol_version_mixin.rb +69 -0
  86. data/lib/right_agent/retryable_request.rb +195 -0
  87. data/lib/right_agent/scripts/agent_controller.rb +543 -0
  88. data/lib/right_agent/scripts/agent_deployer.rb +400 -0
  89. data/lib/right_agent/scripts/common_parser.rb +160 -0
  90. data/lib/right_agent/scripts/log_level_manager.rb +192 -0
  91. data/lib/right_agent/scripts/stats_manager.rb +268 -0
  92. data/lib/right_agent/scripts/usage.rb +58 -0
  93. data/lib/right_agent/secure_identity.rb +92 -0
  94. data/lib/right_agent/security.rb +32 -0
  95. data/lib/right_agent/security/cached_certificate_store_proxy.rb +77 -0
  96. data/lib/right_agent/security/certificate.rb +102 -0
  97. data/lib/right_agent/security/certificate_cache.rb +89 -0
  98. data/lib/right_agent/security/distinguished_name.rb +56 -0
  99. data/lib/right_agent/security/encrypted_document.rb +83 -0
  100. data/lib/right_agent/security/rsa_key_pair.rb +76 -0
  101. data/lib/right_agent/security/signature.rb +86 -0
  102. data/lib/right_agent/security/static_certificate_store.rb +85 -0
  103. data/lib/right_agent/sender.rb +792 -0
  104. data/lib/right_agent/serialize.rb +29 -0
  105. data/lib/right_agent/serialize/message_pack.rb +107 -0
  106. data/lib/right_agent/serialize/secure_serializer.rb +151 -0
  107. data/lib/right_agent/serialize/secure_serializer_initializer.rb +47 -0
  108. data/lib/right_agent/serialize/serializable.rb +151 -0
  109. data/lib/right_agent/serialize/serializer.rb +159 -0
  110. data/lib/right_agent/subprocess.rb +38 -0
  111. data/lib/right_agent/tracer.rb +124 -0
  112. data/right_agent.gemspec +101 -0
  113. data/spec/actor_registry_spec.rb +80 -0
  114. data/spec/actor_spec.rb +162 -0
  115. data/spec/agent_config_spec.rb +235 -0
  116. data/spec/agent_identity_spec.rb +78 -0
  117. data/spec/agent_spec.rb +734 -0
  118. data/spec/agent_tag_manager_spec.rb +319 -0
  119. data/spec/clients/api_client_spec.rb +423 -0
  120. data/spec/clients/auth_client_spec.rb +272 -0
  121. data/spec/clients/balanced_http_client_spec.rb +576 -0
  122. data/spec/clients/base_retry_client_spec.rb +635 -0
  123. data/spec/clients/router_client_spec.rb +594 -0
  124. data/spec/clients/spec_helper.rb +111 -0
  125. data/spec/command/agent_manager_commands_spec.rb +51 -0
  126. data/spec/command/command_io_spec.rb +93 -0
  127. data/spec/command/command_parser_spec.rb +79 -0
  128. data/spec/command/command_runner_spec.rb +107 -0
  129. data/spec/command/command_serializer_spec.rb +51 -0
  130. data/spec/connectivity_checker_spec.rb +83 -0
  131. data/spec/core_payload_types/dev_repositories_spec.rb +64 -0
  132. data/spec/core_payload_types/dev_repository_spec.rb +33 -0
  133. data/spec/core_payload_types/executable_bundle_spec.rb +67 -0
  134. data/spec/core_payload_types/login_user_spec.rb +102 -0
  135. data/spec/core_payload_types/recipe_instantiation_spec.rb +81 -0
  136. data/spec/core_payload_types/right_script_attachment_spec.rb +65 -0
  137. data/spec/core_payload_types/right_script_instantiation_spec.rb +79 -0
  138. data/spec/core_payload_types/spec_helper.rb +23 -0
  139. data/spec/dispatched_cache_spec.rb +136 -0
  140. data/spec/dispatcher_spec.rb +324 -0
  141. data/spec/enrollment_result_spec.rb +53 -0
  142. data/spec/history_spec.rb +246 -0
  143. data/spec/log_spec.rb +192 -0
  144. data/spec/monkey_patches/eventmachine_spec.rb +62 -0
  145. data/spec/multiplexer_spec.rb +48 -0
  146. data/spec/offline_handler_spec.rb +340 -0
  147. data/spec/operation_result_spec.rb +208 -0
  148. data/spec/packets_spec.rb +461 -0
  149. data/spec/pending_requests_spec.rb +136 -0
  150. data/spec/platform/spec_helper.rb +216 -0
  151. data/spec/platform/unix/darwin/platform_spec.rb +181 -0
  152. data/spec/platform/unix/linux/platform_spec.rb +540 -0
  153. data/spec/platform/unix/spec_helper.rb +149 -0
  154. data/spec/platform/windows/mingw/platform_spec.rb +222 -0
  155. data/spec/platform/windows/mswin/platform_spec.rb +259 -0
  156. data/spec/platform/windows/spec_helper.rb +720 -0
  157. data/spec/retryable_request_spec.rb +306 -0
  158. data/spec/secure_identity_spec.rb +50 -0
  159. data/spec/security/cached_certificate_store_proxy_spec.rb +62 -0
  160. data/spec/security/certificate_cache_spec.rb +71 -0
  161. data/spec/security/certificate_spec.rb +49 -0
  162. data/spec/security/distinguished_name_spec.rb +46 -0
  163. data/spec/security/encrypted_document_spec.rb +55 -0
  164. data/spec/security/rsa_key_pair_spec.rb +55 -0
  165. data/spec/security/signature_spec.rb +66 -0
  166. data/spec/security/static_certificate_store_spec.rb +58 -0
  167. data/spec/sender_spec.rb +1045 -0
  168. data/spec/serialize/message_pack_spec.rb +131 -0
  169. data/spec/serialize/secure_serializer_spec.rb +132 -0
  170. data/spec/serialize/serializable_spec.rb +90 -0
  171. data/spec/serialize/serializer_spec.rb +197 -0
  172. data/spec/spec.opts +2 -0
  173. data/spec/spec.win32.opts +1 -0
  174. data/spec/spec_helper.rb +130 -0
  175. data/spec/tracer_spec.rb +114 -0
  176. metadata +447 -0
@@ -0,0 +1,111 @@
1
+ #
2
+ # Copyright (c) 2009-2011 RightScale Inc
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+
23
+ require 'restclient'
24
+
25
+ require ::File.expand_path('../../spec_helper', __FILE__)
26
+
27
+ # Mock auth client providing basic support needed by various clients
28
+ class AuthClientMock < RightScale::AuthClient
29
+ attr_reader :test_url, :expired_called, :redirect_location
30
+
31
+ def initialize(url, auth_header, state = nil, account_id = nil, identity = nil)
32
+ @test_url = @api_url = @router_url = url
33
+ @auth_header = auth_header
34
+ @account_id = account_id
35
+ @identity = identity || "rs-agent-1-1"
36
+ @state = :authorized if state
37
+ end
38
+
39
+ def identity
40
+ @identity
41
+ end
42
+
43
+ def headers
44
+ auth_header
45
+ end
46
+
47
+ def auth_header
48
+ @auth_header
49
+ end
50
+
51
+ def expired
52
+ @expired_called = true
53
+ end
54
+
55
+ def redirect(location)
56
+ @redirect_location = location
57
+ end
58
+ end
59
+
60
+ # Mock WebSocket event
61
+ class WebSocketEventMock
62
+ attr_reader :code, :data, :reason
63
+
64
+ def initialize(data, code = nil, reason = nil)
65
+ @code = code
66
+ @data = data
67
+ @reason = reason
68
+ end
69
+ end
70
+
71
+ # Mock of WebSocket so that can call on methods
72
+ class WebSocketClientMock
73
+ attr_reader :sent, :closed, :code, :reason
74
+
75
+ def send(event)
76
+ @sent = @sent.nil? ? event : (@sent.is_a?(Array) ? @sent << event : [@sent, event])
77
+ end
78
+
79
+ def close(code = nil, reason = nil)
80
+ @code = code
81
+ @reason = reason
82
+ @closed = true
83
+ end
84
+
85
+ def onclose=(block)
86
+ @close_block = block
87
+ end
88
+
89
+ def onclose(code, reason = nil)
90
+ @event = WebSocketEventMock.new(nil, code, reason)
91
+ @close_block.call(@event)
92
+ end
93
+
94
+ def onerror=(block)
95
+ @error_block = block
96
+ end
97
+
98
+ def onerror(data)
99
+ @event = WebSocketEventMock.new(data)
100
+ @error_block.call(@event)
101
+ end
102
+
103
+ def onmessage=(block)
104
+ @message_block = block
105
+ end
106
+
107
+ def onmessage(data)
108
+ @event = WebSocketEventMock.new(data)
109
+ @message_block.call(@event)
110
+ end
111
+ end
@@ -0,0 +1,51 @@
1
+ #
2
+ # Copyright (c) 2009 RightScale Inc
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+
23
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
24
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'lib', 'right_agent', 'command'))
25
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'lib', 'right_agent', 'command', 'agent_manager_commands'))
26
+
27
+ describe RightScale::AgentManagerCommands do
28
+
29
+ before(:all) do
30
+ @commands = RightScale::AgentManagerCommands::COMMANDS
31
+ @agent_identity = RightScale::AgentIdentity.new('rs', 'test', 1).to_s
32
+ end
33
+
34
+ it 'should list commands' do
35
+ flexmock(RightScale::CommandIO.instance).should_receive(:reply).and_return do |conn, r|
36
+ conn.should == 42
37
+ # r is YAML, 2 lines for each command, one less command printed (the list command)
38
+ # plus one header line
39
+ r.count("\n").should == (@commands.reject {|k,_| k.to_s =~ /test/}.size - 1) * 2 + 1
40
+ end
41
+ RightScale::AgentManagerCommands.new("agent_manager").send(:list_command, {:conn => 42}).should be_true
42
+ end
43
+
44
+ it 'should get commands' do
45
+ cmds = RightScale::AgentManagerCommands.get("agent_manager")
46
+ cmds.size.should == @commands.size
47
+ cmds.keys.map { |k| k.to_s }.sort.should == @commands.keys.map { |k| k.to_s }.sort
48
+ cmds.values.all? { |v| v.is_a? Proc }.should be_true
49
+ end
50
+
51
+ end
@@ -0,0 +1,93 @@
1
+ #
2
+ # Copyright (c) 2009-2011 RightScale Inc
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+
23
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
24
+
25
+ module RightScale
26
+ module CommandIoSpec
27
+
28
+ # ensure uniqueness of handler to avoid confusion.
29
+ raise "#{ClientOutputHandler.name} is already defined" if defined?(ClientOutputHandler)
30
+
31
+ module ClientOutputHandler
32
+ def initialize(input)
33
+ @input = input
34
+ end
35
+ def post_init
36
+ send_data(RightScale::CommandSerializer.dump(@input))
37
+ close_connection_after_writing
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ describe RightScale::CommandIO do
44
+
45
+ # Serialize and send given input to command listener
46
+ def send_input(input)
47
+
48
+ EM.connect('127.0.0.1', @socket_port, ::RightScale::CommandIoSpec::ClientOutputHandler, input)
49
+ end
50
+
51
+ before(:all) do
52
+ @socket_port = TEST_SOCKET_PORT
53
+ end
54
+
55
+ it 'should detect missing blocks' do
56
+ lambda { RightScale::CommandIO.instance.listen(@socket_port) }.should raise_error(ArgumentError)
57
+ end
58
+
59
+ it 'should receive a command' do
60
+ @input = ''
61
+ EM.run do
62
+ RightScale::CommandIO.instance.listen(@socket_port) { |input, _| @input = input; stop }
63
+ send_input('input')
64
+ EM.add_timer(2) { stop }
65
+ end
66
+ @input.should == 'input'
67
+ end
68
+
69
+ it 'should receive many commands' do
70
+ @inputs = []
71
+ EM.run do
72
+ RightScale::CommandIO.instance.listen(@socket_port) do |input, _|
73
+ @inputs << input
74
+ stop if input == 'final'
75
+ end
76
+ for i in 1..50 do
77
+ send_input("input#{i}")
78
+ end
79
+ send_input("final")
80
+ EM.add_timer(2) { stop }
81
+ end
82
+
83
+ @inputs.size.should == 51
84
+ (0..49).each { |i| @inputs[i].should == "input#{i+1}" }
85
+ @inputs[50].should == 'final'
86
+ end
87
+
88
+ def stop
89
+ RightScale::CommandIO.instance.stop_listening
90
+ EM.stop
91
+ end
92
+
93
+ end
@@ -0,0 +1,79 @@
1
+ #
2
+ # Copyright (c) 2009-2011 RightScale Inc
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+
23
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
24
+
25
+ describe RightScale::CommandParser do
26
+
27
+ it 'should detect missing block' do
28
+ lambda { RightScale::CommandParser.new }.should raise_error(ArgumentError)
29
+ end
30
+
31
+ it 'should parse' do
32
+ @parser = RightScale::CommandParser.new { |cmd| @command = cmd; EM.stop }
33
+ EM.run do
34
+ @parser.parse_chunk(RightScale::CommandSerializer.dump(42)).should be_true
35
+ EM.add_timer(0.5) { EM.stop }
36
+ end
37
+ @command.should == 42
38
+ end
39
+
40
+ it 'should parse in chunks' do
41
+ data = RightScale::CommandSerializer.dump({ :some => 'random', :and => 'long', :serialized => 'data' })
42
+ data.size.should > 6
43
+ parts = data[0..2], data[3..4], data[5..6], data[7..data.size - 1]
44
+ command = ''
45
+ parser = RightScale::CommandParser.new { |cmd| command = cmd; EM.stop }
46
+ EM.run do
47
+ parts.each { |p| parser.parse_chunk(p) }
48
+ EM.add_timer(0.5) { EM.stop }
49
+ end
50
+ command.should == { :some => 'random', :and => 'long', :serialized => 'data' }
51
+ end
52
+
53
+ it 'should parse multiple commands' do
54
+ commands = []
55
+ sample_data = [42, {:question => 'why?', :answer => 'fourty-two'}]
56
+ parser = RightScale::CommandParser.new { |cmd| commands << cmd; EM.stop if commands.size == sample_data.size }
57
+ serialized = sample_data.inject('') { |s, cmd| s << RightScale::CommandSerializer.dump(cmd) }
58
+ EM.run do
59
+ parser.parse_chunk(serialized).should be_true
60
+ EM.add_timer(0.5) { EM.stop }
61
+ end
62
+ commands.should == sample_data
63
+ end
64
+
65
+ it 'should parse multiple commands in chunks' do
66
+ commands = []
67
+ sample_data = [42, {:question => 'why?', :answer => 'fourty-two'}]
68
+ parser = RightScale::CommandParser.new { |cmd| commands << cmd; EM.stop if commands.size == sample_data.size }
69
+ serialized = sample_data.inject('') { |s, cmd| s << RightScale::CommandSerializer.dump(cmd) }
70
+ serialized.size.should > 10
71
+ parts = serialized[0..2], serialized[3..4], serialized[5..6], serialized[7..serialized.size - 5], serialized[serialized.size - 4..serialized.size - 1]
72
+ EM.run do
73
+ parts.each { |p| parser.parse_chunk(p) }
74
+ EM.add_timer(0.5) { EM.stop }
75
+ end
76
+ commands.should == sample_data
77
+ end
78
+
79
+ end
@@ -0,0 +1,107 @@
1
+ #
2
+ # Copyright (c) 2009-2011 RightScale Inc
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+
23
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
24
+
25
+ module RightScale
26
+
27
+ class CommandIOMock < CommandIO
28
+
29
+ include RightSupport::Ruby::EasySingleton
30
+
31
+ def trigger_listen(payload)
32
+ @test_callback.call(payload)
33
+ end
34
+
35
+ def listen(socket_port, &block)
36
+ @test_callback = block
37
+ true
38
+ end
39
+
40
+ end
41
+
42
+ end
43
+
44
+ describe RightScale::CommandRunner do
45
+
46
+ before(:all) do
47
+ @command_payload = { :name => 'test', :options => 'options' }
48
+ @socket_port = TEST_SOCKET_PORT
49
+ end
50
+
51
+ context :start do
52
+ before(:each) do
53
+ @pid_file = flexmock(RightScale::PidFile)
54
+ @pid_file.should_receive(:exists?).and_return(true)
55
+ @pid_file.should_receive(:set_command_options).and_return(true)
56
+ flexmock(RightScale::PidFile).should_receive(:new).and_return(@pid_file)
57
+ end
58
+
59
+ context 'when a block is provided' do
60
+ before(:each) do
61
+ @block = Proc.new do |pid_file|
62
+ @callback_pid_file = pid_file
63
+ end
64
+ end
65
+
66
+ it 'should yield its PidFile' do
67
+ commands = { :test => lambda { |opt, _| } }
68
+ flexmock(RightScale::CommandIO).should_receive(:instance).and_return(RightScale::CommandIOMock.instance)
69
+ RightScale::CommandRunner.start(@socket_port, RightScale::AgentIdentity.generate, commands, &@block)
70
+ @callback_pid_file.should == @pid_file
71
+ end
72
+ end
73
+ end
74
+
75
+ it 'should handle invalid formats' do
76
+ flexmock(RightScale::CommandIO.instance).should_receive(:listen).and_yield(['invalid yaml'])
77
+ flexmock(RightScale::Log).should_receive(:info).once
78
+ RightScale::CommandRunner.start(@socket_port, RightScale::AgentIdentity.generate, commands={})
79
+ end
80
+
81
+ it 'should handle non-existent commands' do
82
+ flexmock(RightScale::CommandIO.instance).should_receive(:listen).and_yield(@command_payload)
83
+ flexmock(RightScale::Log).should_receive(:info).once
84
+ RightScale::CommandRunner.start(@socket_port, RightScale::AgentIdentity.generate, commands={})
85
+ end
86
+
87
+ it 'should run commands' do
88
+ commands = { :test => lambda { |opt, _| @opt = opt } }
89
+ flexmock(RightScale::CommandIO).should_receive(:instance).and_return(RightScale::CommandIOMock.instance)
90
+ cmd_options = RightScale::CommandRunner.start(@socket_port, RightScale::AgentIdentity.generate, commands)
91
+ payload = @command_payload.merge(cmd_options)
92
+ RightScale::CommandIOMock.instance.trigger_listen(payload)
93
+ @opt.should == payload
94
+ end
95
+
96
+ it 'should run commands using fiber pool if provided' do
97
+ commands = { :test => lambda { |opt, _| @opt = opt } }
98
+ fiber_pool = flexmock("fiber pool")
99
+ fiber_pool.should_receive(:spawn).and_return(true).and_yield.once
100
+ flexmock(RightScale::CommandIO).should_receive(:instance).and_return(RightScale::CommandIOMock.instance)
101
+ cmd_options = RightScale::CommandRunner.start(@socket_port, RightScale::AgentIdentity.generate, commands, fiber_pool)
102
+ payload = @command_payload.merge(cmd_options)
103
+ RightScale::CommandIOMock.instance.trigger_listen(payload)
104
+ @opt.should == payload
105
+ end
106
+
107
+ end
@@ -0,0 +1,51 @@
1
+ #
2
+ # Copyright (c) 2009-2011 RightScale Inc
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+
23
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
24
+
25
+ describe RightScale::CommandSerializer do
26
+
27
+ before(:all) do
28
+ @sample_data = [ 42, 'fourty two', { :haha => 42, 'hoho' => 'fourty_two' }]
29
+ end
30
+
31
+ it 'should serialize' do
32
+ @sample_data.each do |data|
33
+ RightScale::CommandSerializer.dump(data)
34
+ end
35
+ end
36
+
37
+ it 'should deserialize' do
38
+ @sample_data.each do |data|
39
+ RightScale::CommandSerializer.load(RightScale::CommandSerializer.dump(data)).should == data
40
+ end
41
+ end
42
+
43
+ it 'should add separators' do
44
+ serialized = ''
45
+ @sample_data.each do |data|
46
+ serialized << RightScale::CommandSerializer.dump(data)
47
+ end
48
+ serialized.split(RightScale::CommandSerializer::SEPARATOR).size.should == @sample_data.size
49
+ end
50
+
51
+ end