right_agent 2.0.7-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
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,149 @@
1
+ #
2
+ # Copyright (c) 2013 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('../../spec_helper', __FILE__)
24
+
25
+ require 'stringio'
26
+
27
+ shared_examples_for 'supports unix platform filesystem' do
28
+
29
+ context '#find_executable_in_path' do
30
+ let(:path_env) { '/usr/local/bin:/usr/bin:/bin' }
31
+
32
+ it 'should find executable' do
33
+ mock_env = flexmock(::ENV)
34
+ mock_env.should_receive(:[]).with('PATH').and_return(path_env)
35
+
36
+ file_class.should_receive(:executable?).with('/usr/local/bin/foo').and_return(false).twice
37
+ file_class.should_receive(:executable?).with('/usr/bin/foo').and_return(true).twice
38
+ file_class.should_receive(:executable?).with('/usr/local/bin/bar').and_return(false).twice
39
+ file_class.should_receive(:executable?).with('/usr/bin/bar').and_return(false).twice
40
+ file_class.should_receive(:executable?).with('/bin/bar').and_return(false).twice
41
+
42
+ subject.find_executable_in_path('foo').should == '/usr/bin/foo'
43
+ subject.has_executable_in_path('foo').should be_true
44
+ subject.find_executable_in_path('bar').should be_nil
45
+ subject.has_executable_in_path('bar').should be_false
46
+ end
47
+ end # find_executable_in_path
48
+
49
+ context 'paths' do
50
+ it 'should return unix path constants' do
51
+ subject.right_agent_cfg_dir.should == '/var/lib/rightscale/right_agent'
52
+ subject.right_scale_static_state_dir.should == '/etc/rightscale.d'
53
+ subject.right_link_static_state_dir.should == '/etc/rightscale.d/right_link'
54
+ subject.right_link_dynamic_state_dir.should == '/var/lib/rightscale/right_link'
55
+ subject.spool_dir.should == '/var/spool'
56
+ subject.ssh_cfg_dir.should == '/etc/ssh'
57
+ subject.cache_dir.should == '/var/cache'
58
+ subject.log_dir.should == '/var/log'
59
+ subject.source_code_dir.should == '/usr/src'
60
+ subject.temp_dir.should == '/tmp'
61
+ subject.pid_dir.should == '/var/run'
62
+ subject.right_link_home_dir.should == '/opt/rightscale'
63
+ subject.private_bin_dir.should == '/opt/rightscale/bin'
64
+ subject.sandbox_dir.should == '/opt/rightscale/sandbox'
65
+ end
66
+
67
+ it 'should return unmodified paths from Windows compatibility methods' do
68
+ path = '/tmp/some_path_to_test'
69
+ subject.long_path_to_short_path(path).should == path
70
+ subject.pretty_path(path, false).should == path
71
+ subject.pretty_path(path, true).should == path
72
+ subject.ensure_local_drive_path(path, 'foo').should == path
73
+ end
74
+ end # paths
75
+
76
+ context '#create_symlink' do
77
+ it 'should use ruby file to create symlink (under unix)' do
78
+ file_class.should_receive(:symlink).with('/tmp/from', '/tmp/to').and_return(0)
79
+ subject.create_symlink('/tmp/from', '/tmp/to').should == 0
80
+ end
81
+ end # create_symlink
82
+ end # supports unix platform filesystem
83
+
84
+ shared_examples_for 'supports unix platform shell' do
85
+ it_should_behave_like 'supports any platform shell'
86
+
87
+ context 'paths' do
88
+ it 'should return path constants for unix' do
89
+ subject.null_output_name.should == '/dev/null'
90
+ subject.sandbox_ruby.should == '/opt/rightscale/sandbox/bin/ruby'
91
+ end
92
+ end # paths
93
+
94
+ context 'commands' do
95
+ it 'should return unmodified commands from Windows compatibility methods' do
96
+ cmd = 'sh -c echo foo'
97
+ subject.format_script_file_name(cmd).should == cmd
98
+ subject.format_script_file_name(cmd, '.foo').should == cmd
99
+ end
100
+
101
+ [:format_executable_command, :format_shell_command].each do |methud|
102
+ context methud do
103
+ it 'should format commands' do
104
+ subject.send(methud, 'foo').should == 'foo'
105
+ subject.send(methud, 'bar', 'foo').should == 'bar foo'
106
+ subject.send(methud, 'baz', 'a b', "c'd", 'foo').should == "baz \"a b\" \"c'd\" foo"
107
+ end
108
+ end # methud
109
+ end # for each method (having identical behavior under unix)
110
+
111
+ it 'should format ruby commands using sandbox ruby' do
112
+ script_path = '/tmp/foo.rb'
113
+ subject.format_ruby_command(script_path).should == '/opt/rightscale/sandbox/bin/ruby /tmp/foo.rb'
114
+ subject.format_ruby_command(script_path, 'bar').should == '/opt/rightscale/sandbox/bin/ruby /tmp/foo.rb bar'
115
+ end
116
+ end # commands
117
+ end # supports unix platform shell
118
+
119
+ shared_examples_for 'supports unix platform rng' do
120
+ context '#pseudorandom_bytes' do
121
+ it 'should read requested byte length from urandom device under unix' do
122
+ sio = StringIO.new
123
+ buffer = 0.chr * 256
124
+ 256.times.each { |i| buffer[i] = i.chr }
125
+ sio.write buffer
126
+ sio.rewind
127
+ file_class.should_receive(:open).with('/dev/urandom', 'r', Proc).and_yield(sio)
128
+ subject.pseudorandom_bytes(16).should == buffer[0, 16]
129
+ subject.pseudorandom_bytes(32).should == buffer[16, 32]
130
+ end
131
+ end # pseudorandom_bytes
132
+ end # supports unix platform rng
133
+
134
+ shared_examples_for 'supports unix platform process' do
135
+ context '#resident_set_size' do
136
+ it 'should return resident set size for current process' do
137
+ cmd = "ps -o rss= -p #{$$}"
138
+ platform_class.should_receive(:execute).with(cmd, {}).and_return('12345').once
139
+ subject.resident_set_size.should == 12345
140
+ end
141
+
142
+ it 'should return resident set size for other process' do
143
+ pid = 789
144
+ cmd = "ps -o rss= -p #{pid}"
145
+ platform_class.should_receive(:execute).with(cmd, {}).and_return('23456').once
146
+ subject.resident_set_size(pid).should == 23456
147
+ end
148
+ end # pseudorandom_bytes
149
+ end # supports unix platform rng
@@ -0,0 +1,222 @@
1
+ #
2
+ # Copyright (c) 2013 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('../../spec_helper', __FILE__)
24
+
25
+ # stub FII for testing on non-mingw platforms; any mingw-specific tests must
26
+ # mock API calls.
27
+ module FFI
28
+ module Library
29
+
30
+ def typedef(*args)
31
+ true
32
+ end
33
+
34
+ def ffi_lib(*args)
35
+ true
36
+ end
37
+
38
+ def ffi_convention(*args)
39
+ true
40
+ end
41
+
42
+ def attach_function(*args)
43
+ true
44
+ end
45
+ end
46
+ end
47
+
48
+ describe RightScale::Platform do
49
+
50
+ include PlatformSpecHelper
51
+
52
+ context 'windows/mingw' do
53
+
54
+ # required by before_all_platform_tests
55
+ # called by before(:all) so not defined using let().
56
+ def expected_genus; :windows; end
57
+ def expected_species; :mingw; end
58
+
59
+ def to_wide(str)
60
+ str.encode(::RightScale::Platform::PlatformHelperBase::WIDE)
61
+ end
62
+
63
+ def instrument_win32_error(error_code, error_message)
64
+ flexmock(::FFI).should_receive(:errno).and_return(error_code).once
65
+ flexmock(described_class::WindowsCommon::API).
66
+ should_receive(:FormatMessageW).
67
+ with(0x1200, nil, error_code, 0, String, Integer, nil).
68
+ and_return do |flags, _, message_id, _, unicode_buffer, _, _|
69
+ if flags == 0x1200 && message_id == 5
70
+ unicode_message = to_wide(error_message)
71
+ unicode_message.chars.each_with_index do |c, index|
72
+ unicode_buffer[index] = c
73
+ end
74
+ unicode_message.length
75
+ else
76
+ fail "Unexpected arguments: #{[flags, message_id].inspect}"
77
+ end
78
+ end.once
79
+ end
80
+
81
+ before(:all) do
82
+ before_all_platform_tests
83
+ end
84
+
85
+ after(:all) do
86
+ after_all_platform_tests
87
+ end
88
+
89
+ before(:each) do
90
+ before_each_platform_test
91
+ end
92
+
93
+ after(:each) do
94
+ after_each_platform_test
95
+ end
96
+
97
+ context :statics do
98
+ subject { platform_class }
99
+
100
+ it_should_behave_like 'supports windows platform statics'
101
+ end
102
+
103
+ context :initialization do
104
+ def instrument_os_info(major, minor, build)
105
+ flexmock(::FFI).should_receive(:errno).and_return(0).once
106
+ flexmock(described_class::WindowsSystemInformation::API).
107
+ should_receive(:GetVersionExW).
108
+ with(String).
109
+ and_return do |vib|
110
+ vib[4,12] = [major, minor, build].pack('LLL')
111
+ end.once
112
+ end
113
+
114
+ it_should_behave_like 'supports windows platform initialization'
115
+ end # initialization
116
+
117
+ context :controller do
118
+ subject { described_class.controller }
119
+
120
+ def instrument_initiate_system_shutdown_api(reboot_after_shutdown)
121
+ controller_api = flexmock(described_class::Controller::API)
122
+ process_api = flexmock(described_class::Process::API)
123
+ windows_common_api = flexmock(described_class::WindowsCommon::API)
124
+ windows_security_api = flexmock(described_class::WindowsSecurity::API)
125
+
126
+ process_api.should_receive(:GetCurrentProcess).and_return(-1).once
127
+ process_api.should_receive(:OpenProcessToken).and_return(true).once
128
+ windows_security_api.should_receive(:LookupPrivilegeValueW).and_return(true).once
129
+ windows_security_api.should_receive(:AdjustTokenPrivileges).and_return(true).once
130
+ controller_api.
131
+ should_receive(:InitiateSystemShutdownW).
132
+ with(nil, nil, 1, true, reboot_after_shutdown).
133
+ and_return(true).
134
+ once
135
+ windows_common_api.should_receive(:CloseHandle).and_return(true).once
136
+ end
137
+
138
+ it_should_behave_like 'supports windows platform controller'
139
+ end # controller
140
+
141
+ context :filesystem do
142
+ subject { flexmock(described_class.filesystem) }
143
+
144
+ def instrument_create_symbolic_link_api(from_path, to_path, flags, &callback)
145
+ flexmock(described_class::Filesystem::API).
146
+ should_receive(:CreateSymbolicLinkW).
147
+ with(to_wide(to_path + 0.chr), to_wide(from_path + 0.chr), flags).
148
+ and_return { callback.call == 0 ? false : true }.
149
+ once
150
+ end
151
+
152
+ def instrument_get_short_path_name_api(long_path, short_path_from_api, &callback)
153
+ flexmock(described_class::Filesystem::API).
154
+ should_receive(:GetShortPathNameW).
155
+ with(to_wide(long_path + 0.chr), String, Integer).
156
+ and_return do |lp, short_path_buffer, _|
157
+ to_wide(short_path_from_api).chars.each_with_index do |c, index|
158
+ short_path_buffer[index] = c
159
+ end
160
+ callback.call
161
+ end.once
162
+ end
163
+
164
+ def instrument_get_temp_path_api(temp_path_from_api, &callback)
165
+ flexmock(described_class::Filesystem::API).
166
+ should_receive(:GetTempPathW).
167
+ with(Integer, String).
168
+ and_return do |_, buffer|
169
+ to_wide(temp_path_from_api).chars.each_with_index do |c, index|
170
+ buffer[index] = c
171
+ end
172
+ callback.call
173
+ end.once
174
+ end
175
+
176
+ it_should_behave_like 'supports windows platform filesystem'
177
+ end # filesystem
178
+
179
+ context :installer do
180
+ subject { described_class.installer }
181
+
182
+ it_should_behave_like 'supports windows platform installer'
183
+ end # installer
184
+
185
+ context :shell do
186
+ subject { flexmock(described_class.shell) }
187
+
188
+ it_should_behave_like 'supports windows platform shell'
189
+ end # shell
190
+
191
+ context :rng do
192
+ subject { described_class.rng }
193
+
194
+ it_should_behave_like 'supports windows platform rng'
195
+ end # rng
196
+
197
+ context :process do
198
+ subject { described_class.process }
199
+
200
+ def instrument_get_process_memory_info_api(resident_set_size)
201
+ process_api = flexmock(described_class::Process::API)
202
+ process_api.should_receive(:GetCurrentProcess).and_return(-1).once
203
+ process_api.
204
+ should_receive(:GetProcessMemoryInfo).
205
+ with(-1, String, Integer).
206
+ and_return do |_, pmib, _|
207
+ pmib[3 * 4, 4] = [resident_set_size * 1024].pack('L')
208
+ true
209
+ end.once
210
+ end
211
+
212
+ it_should_behave_like 'supports windows platform process'
213
+ end # process
214
+
215
+ context :volume_manager do
216
+ subject { flexmock(described_class.volume_manager) }
217
+
218
+ it_should_behave_like 'supports windows platform volume manager'
219
+ end # volume_manager
220
+
221
+ end # windows/mingw
222
+ end # RightScale::Platform
@@ -0,0 +1,259 @@
1
+ #
2
+ # Copyright (c) 2013 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('../../spec_helper', __FILE__)
24
+
25
+ # stub out definition of ::Win32::API for testing on non-Windows platforms.
26
+ module Win32
27
+ class API; end
28
+ end
29
+
30
+ describe RightScale::Platform do
31
+
32
+ include PlatformSpecHelper
33
+
34
+ context 'windows/mswin' do
35
+
36
+ # required by before_all_platform_tests
37
+ # called by before(:all) so not defined using let().
38
+ def expected_genus; :windows; end
39
+ def expected_species; :mswin; end
40
+
41
+ def instrument_win32_error(error_code, error_message)
42
+ w32a = flexmock(::Win32::API)
43
+ w32a.
44
+ should_receive(:new).
45
+ with('GetLastError', 'V', 'L', 'kernel32').
46
+ and_return(lambda { error_code }).
47
+ once
48
+ w32a.
49
+ should_receive(:new).
50
+ with('FormatMessage', 'LLLLPLP', 'L', 'kernel32').
51
+ and_return do
52
+ lambda do |flags, _, message_id, _, buffer, _, _|
53
+
54
+ if flags == 0x1200 && message_id == 5
55
+ error_message.chars.each_with_index do |c, index|
56
+ buffer[index] = c
57
+ end
58
+ error_message.length
59
+ else
60
+ fail "Unexpected arguments: #{[mn, m, t, tac, ras].inspect}"
61
+ end
62
+ end
63
+ end.once
64
+ end
65
+
66
+ before(:all) do
67
+ before_all_platform_tests
68
+ end
69
+
70
+ after(:all) do
71
+ after_all_platform_tests
72
+ end
73
+
74
+ before(:each) do
75
+ before_each_platform_test
76
+ end
77
+
78
+ after(:each) do
79
+ after_each_platform_test
80
+ end
81
+
82
+ context :statics do
83
+ subject { platform_class }
84
+
85
+ it_should_behave_like 'supports windows platform statics'
86
+ end
87
+
88
+ context :initialization do
89
+ def instrument_os_info(major, minor, build)
90
+ w32a = flexmock(::Win32::API)
91
+ w32a.
92
+ should_receive(:new).
93
+ with('GetLastError', 'V', 'L', 'kernel32').
94
+ and_return(lambda { 0 }).
95
+ once
96
+ w32a.
97
+ should_receive(:new).
98
+ with('GetVersionEx', 'P', 'L', 'kernel32').
99
+ and_return(
100
+ lambda do |vib|
101
+ vib[4,12] = [major, minor, build].pack('LLL')
102
+ 1
103
+ end
104
+ ).once
105
+ end
106
+
107
+ it_should_behave_like 'supports windows platform initialization'
108
+ end # initialization
109
+
110
+ context :controller do
111
+ subject { described_class.controller }
112
+
113
+ def instrument_initiate_system_shutdown_api(reboot_after_shutdown)
114
+ w32a = flexmock(::Win32::API)
115
+ w32a.
116
+ should_receive(:new).
117
+ with('GetCurrentProcess', 'V', 'L', 'kernel32').
118
+ and_return(lambda { -1 }).
119
+ once
120
+ w32a.
121
+ should_receive(:new).
122
+ with('OpenProcessToken', 'LLP', 'B', 'advapi32').
123
+ and_return(lambda { |ph, da, th| 1 }).
124
+ once
125
+ w32a.
126
+ should_receive(:new).
127
+ with('LookupPrivilegeValue', 'PPP', 'B', 'advapi32').
128
+ and_return(lambda { |sn, n, luid| 1 }).
129
+ once
130
+ w32a.
131
+ should_receive(:new).
132
+ with('AdjustTokenPrivileges', 'LLPLPP', 'B', 'advapi32').
133
+ and_return(lambda { |th, dap, ns, bl, ps, rl| 1 }).
134
+ once
135
+ w32a.
136
+ should_receive(:new).
137
+ with('InitiateSystemShutdown', 'PPLLL', 'B', 'advapi32').
138
+ and_return(
139
+ lambda do |mn, m, t, tac, ras|
140
+ if mn == 0 && m == 0 && t == 1 && tac == 1 && ras == (reboot_after_shutdown ? 1 : 0)
141
+ 1
142
+ else
143
+ fail "Unexpected arguments: #{[mn, m, t, tac, ras].inspect}"
144
+ end
145
+ end
146
+ ).once
147
+ w32a.
148
+ should_receive(:new).
149
+ with('CloseHandle', 'L', 'B', 'kernel32').
150
+ and_return(lambda { |h| 1 }).
151
+ once
152
+ end
153
+
154
+ it_should_behave_like 'supports windows platform controller'
155
+ end # controller
156
+
157
+ context :filesystem do
158
+ subject { flexmock(described_class.filesystem) }
159
+
160
+ def instrument_create_symbolic_link_api(from_path, to_path, flags, &callback)
161
+ flexmock(::Win32::API).
162
+ should_receive(:new).
163
+ with('CreateSymbolicLink', 'SSL', 'B', 'kernel32').
164
+ and_return(
165
+ lambda do |tp, fp, fgs|
166
+ if fp == (from_path + 0.chr) && tp == (to_path + 0.chr) && fgs == flags
167
+ callback.call
168
+ else
169
+ fail "Unexpected arguments: #{[tp, fp, fgs].inspect}"
170
+ end
171
+ end
172
+ ).once
173
+ end
174
+
175
+ def instrument_get_short_path_name_api(long_path, short_path_from_api, &callback)
176
+ flexmock(::Win32::API).
177
+ should_receive(:new).
178
+ with('GetShortPathName', 'SPL', 'L', 'kernel32').
179
+ and_return(
180
+ lambda do |lp, short_path_buffer, short_path_buffer_length|
181
+ if lp == (long_path + 0.chr)
182
+ short_path_from_api.chars.each_with_index do |c, index|
183
+ short_path_buffer[index] = c
184
+ end
185
+ callback.call
186
+ else
187
+ fail "Unexpected arguments: #{lp.inspect}"
188
+ end
189
+ end
190
+ ).once
191
+ end
192
+
193
+ def instrument_get_temp_path_api(temp_path_from_api, &callback)
194
+ flexmock(::Win32::API).
195
+ should_receive(:new).
196
+ with('GetTempPath', 'LP', 'L', 'kernel32').
197
+ and_return(
198
+ lambda do |buffer_length, buffer|
199
+ temp_path_from_api.chars.each_with_index do |c, index|
200
+ buffer[index] = c
201
+ end
202
+ callback.call
203
+ end
204
+ ).once
205
+ end
206
+
207
+ it_should_behave_like 'supports windows platform filesystem'
208
+ end # filesystem
209
+
210
+ context :installer do
211
+ subject { described_class.installer }
212
+
213
+ it_should_behave_like 'supports windows platform installer'
214
+ end # installer
215
+
216
+ context :shell do
217
+ subject { flexmock(described_class.shell) }
218
+
219
+ it_should_behave_like 'supports windows platform shell'
220
+ end # shell
221
+
222
+ context :rng do
223
+ subject { described_class.rng }
224
+
225
+ it_should_behave_like 'supports windows platform rng'
226
+ end # rng
227
+
228
+ context :process do
229
+ subject { described_class.process }
230
+
231
+ def instrument_get_process_memory_info_api(resident_set_size)
232
+ w32a = flexmock(::Win32::API)
233
+ w32a.
234
+ should_receive(:new).
235
+ with('GetCurrentProcess', 'V', 'L', 'kernel32').
236
+ and_return(lambda { -1 }).
237
+ once
238
+ w32a.
239
+ should_receive(:new).
240
+ with('GetProcessMemoryInfo', 'LPL', 'B', 'psapi').
241
+ and_return(
242
+ lambda do |ph, pmib, pmibs|
243
+ pmib[3 * 4, 4] = [resident_set_size * 1024].pack('L')
244
+ 1
245
+ end
246
+ ).once
247
+ end
248
+
249
+ it_should_behave_like 'supports windows platform process'
250
+ end # process
251
+
252
+ context :volume_manager do
253
+ subject { flexmock(described_class.volume_manager) }
254
+
255
+ it_should_behave_like 'supports windows platform volume manager'
256
+ end # volume_manager
257
+
258
+ end # windows/mswin
259
+ end # RightScale::Platform