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,136 @@
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(File.join(File.dirname(__FILE__), 'spec_helper'))
24
+
25
+ describe RightScale::PendingRequest do
26
+
27
+ context :initialize do
28
+ it "creates pending request" do
29
+ now = Time.now
30
+ response_handler = lambda { |_| }
31
+ pending_request = RightScale::PendingRequest.new(:send_request, now, response_handler)
32
+ pending_request.kind.should == :send_request
33
+ pending_request.receive_time.should == now
34
+ pending_request.response_handler.should == response_handler
35
+ pending_request.retry_parent_token.should be_nil
36
+ pending_request.non_delivery.should be_nil
37
+ end
38
+ end
39
+
40
+ context :retry_parent_token do
41
+ it "can be set" do
42
+ pending_request = RightScale::PendingRequest.new(:send_request, Time.now, lambda { |_| })
43
+ pending_request.retry_parent_token = "retry token"
44
+ pending_request.retry_parent_token.should == "retry token"
45
+ end
46
+ end
47
+
48
+ context :non_delivery do
49
+ it "can be set" do
50
+ pending_request = RightScale::PendingRequest.new(:send_request, Time.now, lambda { |_| })
51
+ pending_request.non_delivery = "because"
52
+ pending_request.non_delivery.should == "because"
53
+ end
54
+ end
55
+ end
56
+
57
+ describe RightScale::PendingRequests do
58
+
59
+ # Add specified kinds of pending requests to pending_requests hash
60
+ def add_requests(pending_requests, kinds)
61
+ i = 0
62
+ kinds.each do |kind|
63
+ i += 1
64
+ pending_requests["token#{i}"] = RightScale::PendingRequest.new(kind, Time.now, lambda { |_| })
65
+ end
66
+ end
67
+
68
+ before(:all) do
69
+ @push = :send_push
70
+ @request = :send_request
71
+ end
72
+
73
+ context :initialize do
74
+ it "is a hash" do
75
+ pending_requests = RightScale::PendingRequests.new
76
+ pending_requests.should be_a(Hash)
77
+ pending_requests.size.should == 0
78
+ end
79
+ end
80
+
81
+ context :[]= do
82
+ it "stores pending request" do
83
+ pending_requests = RightScale::PendingRequests.new
84
+ pending_request = RightScale::PendingRequest.new(:send_request, Time.now, lambda { |_| })
85
+ pending_requests["token"] = pending_request
86
+ pending_requests["token"].should == pending_request
87
+ end
88
+
89
+ it "deletes old pending send_push requests" do
90
+ now = Time.now
91
+ age = RightScale::PendingRequests::MAX_PUSH_AGE + 21
92
+ flexmock(Time).should_receive(:now).and_return(now, now + 10, now + 10, now + 20, now + 20, now + age, now + age)
93
+ pending_requests = RightScale::PendingRequests.new
94
+ add_requests(pending_requests, [@request, @push, @push])
95
+ pending_requests.size.should == 2
96
+ pending_requests["token1"].should_not be_nil
97
+ pending_requests["token2"].should be_nil
98
+ pending_requests["token3"].should_not be_nil
99
+ pending_requests.instance_variable_get(:@last_cleanup).should == now + age
100
+ end
101
+ end
102
+
103
+ context :kind do
104
+ it "returns pending requests of specified kind" do
105
+ pending_requests = RightScale::PendingRequests.new
106
+ add_requests(pending_requests, [@request, @push, @push])
107
+ requests = pending_requests.kind(:send_request)
108
+ requests.size.should == 1
109
+ requests["token1"].should_not be_nil
110
+ requests = pending_requests.kind(:send_push)
111
+ requests.size.should == 2
112
+ requests["token2"].should_not be_nil
113
+ requests["token3"].should_not be_nil
114
+ end
115
+ end
116
+
117
+ context :youngest_age do
118
+ it "returns age of youngest pending request" do
119
+ now = Time.now
120
+ flexmock(Time).should_receive(:now).and_return(now, now + 10, now + 10, now + 20, now + 20, now + 30)
121
+ pending_requests = RightScale::PendingRequests.new
122
+ add_requests(pending_requests, [@request, @push])
123
+ pending_requests.youngest_age.should == 10
124
+ end
125
+ end
126
+
127
+ context :oldest_age do
128
+ it "returns age of oldest pending request" do
129
+ now = Time.now
130
+ flexmock(Time).should_receive(:now).and_return(now, now + 10, now + 10, now + 20, now + 20, now + 30)
131
+ pending_requests = RightScale::PendingRequests.new
132
+ add_requests(pending_requests, [@request, @push])
133
+ pending_requests.oldest_age.should == 20
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,216 @@
1
+ #
2
+ # Copyright (c) 2009-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
+ # reloads the Platform overrides for the current platform under test and then
26
+ # restores the default platform to avoid breaking subsequent spec tests. works
27
+ # because each implementation is expected to fully override the methods in the
28
+ # base Platform class and so support multiple redefinition.
29
+ #
30
+ # requires the following to be defined by spec in a platform-specific manner:
31
+ # instrument_booted_at
32
+ module PlatformSpecHelper
33
+
34
+ # references mocked Platform class and instance to simplify singleton testing.
35
+ attr_reader :file_class, :platform_class, :platform_instance
36
+
37
+ # resets the Platform singleton.
38
+ def reset_platform_singleton
39
+ # release any existing singleton to force full reload from source.
40
+ ::RightScale::Platform.instance_variable_set(:@singleton__instance__, nil)
41
+ true
42
+ end
43
+
44
+ # Invoke within a before(:all) in described class.
45
+ def before_all_platform_tests
46
+ return true if RUBY_VERSION =~ /^1\.8/ # see below
47
+
48
+ reset_platform_singleton
49
+
50
+ # redefine Platform#initialize_platform_specific to defeat load-upon-
51
+ # initialize behavior of singleton and give us a chance to set genus/species
52
+ # explicitly before any loading occurs.
53
+ ::RightScale::Platform.class_eval('def initialize_platform_specific; end')
54
+
55
+ instance = ::RightScale::Platform.instance
56
+ instance.instance_variable_set(:@genus, expected_genus)
57
+ instance.instance_variable_set(:@species, expected_species)
58
+
59
+ # invoke require logic for load-once behavior.
60
+ unless instance.send(:load_platform_specific)
61
+ # forcibly reload platform under test when require returns false.
62
+ load instance.send(:platform_base_path) + '.rb'
63
+ load instance.send(:platform_genus_path) + '.rb'
64
+ load instance.send(:platform_species_path) + '.rb'
65
+ end
66
+ ::RightScale::Platform.genus.should == expected_genus
67
+ ::RightScale::Platform.species.should == expected_species
68
+ true
69
+ end
70
+
71
+ # Invoke within a after(:all) in described class.
72
+ def after_all_platform_tests
73
+ return true if RUBY_VERSION =~ /^1\.8/ # see below
74
+
75
+ # 'restore' original singleton. this does not undefine any additional nested
76
+ # classes that are platform-specific (for other than the current platform)
77
+ # but they will not be invoked and so are harmless.
78
+ reset_platform_singleton
79
+ instance = ::RightScale::Platform.instance
80
+ load instance.send(:platform_base_path) + '.rb'
81
+ load instance.send(:platform_genus_path) + '.rb'
82
+ load instance.send(:platform_species_path) + '.rb'
83
+ instance.send(:initialize_genus)
84
+ instance.send(:initialize_species)
85
+ true
86
+ end
87
+
88
+ # Invoke within a before(:each) in described class.
89
+ def before_each_platform_test
90
+ # TEAL FIX might be that flexmock version is too new for ruby 1.8 to work,
91
+ # but not really important going forward.
92
+ if RUBY_VERSION =~ /^1\.8/
93
+ pending 'before(:all) mocks do not work in ruby 1.8'
94
+ end
95
+
96
+ # reset singleton again but no need to reload platform code at this point.
97
+ # the issue is that flexmock needs a fresh instance to mock out each time or
98
+ # else the mock teardown goes haywire and spews meaningless stack-traces to
99
+ # the console. the problem seems to be exacerbated by these tests redefining
100
+ # methods of Platform (out of necessity).
101
+ reset_platform_singleton
102
+ platform = ::RightScale::Platform
103
+ instance = platform.instance
104
+ instance.instance_variable_set(:@genus, expected_genus)
105
+ instance.instance_variable_set(:@species, expected_species)
106
+
107
+ # create mocks.
108
+ @file_class = flexmock(::File)
109
+ @platform_class = flexmock(platform)
110
+ @platform_instance = flexmock(instance)
111
+
112
+ # require normalize_path to be mocked during spec runs as it actually
113
+ # invokes APIs on Windows.
114
+ file_class.should_receive(:normalize_path).and_return do |*args|
115
+ raise ::NotImplementedError, "Must mock all calls to File.normalize_path: #{args.inspect}"
116
+ end.by_default
117
+
118
+ # defeat any shell execution by default (i.e. until properly mocked).
119
+ platform_class.should_receive(:execute).and_return do |*args|
120
+ raise ::NotImplementedError, "Must mock all calls to Platform.execute for class: #{args.inspect}"
121
+ end.by_default
122
+ platform_instance.should_receive(:execute).and_return do |*args|
123
+ raise ::NotImplementedError, "Must instrument all calls to Platform#execute for instance: #{args.inspect}"
124
+ end.by_default
125
+ ::RightScale::Platform.genus.should == expected_genus
126
+ ::RightScale::Platform.species.should == expected_species
127
+ expect { ::RightScale::Platform.execute(nil) }.to raise_error(::NotImplementedError)
128
+ expect { ::RightScale::Platform.instance.execute(nil) }.to raise_error(::NotImplementedError)
129
+ true
130
+ end
131
+
132
+ # Invoke within a after(:each) in described class.
133
+ def after_each_platform_test
134
+ @file_class = nil
135
+ @platform_class = nil
136
+ @platform_instance = nil
137
+ true
138
+ end
139
+
140
+ end # PlatformSpecHelper
141
+
142
+ shared_examples_for 'supports any platform shell' do
143
+ let(:minimum_uptime) { 10 * 60 }
144
+ let(:expected_booted_at) { ::Time.now.to_i - minimum_uptime }
145
+
146
+ # Sleeps until timer ticks over. Note that sleep(1) does not guarantee
147
+ # a tick-over and it may take sleep(< 1) to observe the tick-over.
148
+ def wait_for_tick_change
149
+ start_tick = ::Time.now.to_i
150
+ while ::Time.now.to_i == start_tick
151
+ sleep 0.1
152
+ end
153
+ true
154
+ end
155
+
156
+ context '#format_redirect_stdout' do
157
+ it 'should format redirect of stdout' do
158
+ subject.format_redirect_stdout('foo bar').
159
+ should == "foo bar 1>#{subject.null_output_name}"
160
+ subject.format_redirect_stdout('bar foo', '/tmp/foo').
161
+ should == 'bar foo 1>/tmp/foo'
162
+ end
163
+ end # format_redirect_stdout
164
+
165
+ context '#format_redirect_stderr' do
166
+ it 'should format redirect of stderr' do
167
+ subject.format_redirect_stderr('foo bar').
168
+ should == "foo bar 2>#{subject.null_output_name}"
169
+ subject.format_redirect_stderr('bar foo', '/tmp/foo').
170
+ should == 'bar foo 2>/tmp/foo'
171
+ end
172
+ end # format_redirect_stderr
173
+
174
+ context '#format_redirect_both' do
175
+ it 'should format redirect of stderr' do
176
+ subject.format_redirect_both('foo bar').
177
+ should == "foo bar 1>#{subject.null_output_name} 2>&1"
178
+ subject.format_redirect_both('bar foo', '/tmp/foo').
179
+ should == 'bar foo 1>/tmp/foo 2>&1'
180
+ end
181
+ end # format_redirect_both
182
+
183
+ context '#uptime' do
184
+ it 'should be positive' do
185
+ instrument_booted_at(expected_booted_at) { minimum_uptime }
186
+ subject.uptime.should >= minimum_uptime
187
+ end
188
+
189
+ it 'should be strictly increasing' do
190
+ uptime = minimum_uptime
191
+ instrument_booted_at(expected_booted_at) { uptime }
192
+ u0 = subject.uptime
193
+ wait_for_tick_change # uptime may use either system data or a relative time
194
+ uptime += 1
195
+ u1 = subject.uptime
196
+ (u1 - u0).should > 0.0
197
+ end
198
+ end # uptime
199
+
200
+ context '#booted_at' do
201
+ it 'should be some time in the past' do
202
+ instrument_booted_at(expected_booted_at) { minimum_uptime }
203
+ subject.booted_at.should == expected_booted_at
204
+ end
205
+
206
+ it 'should be constant' do
207
+ uptime = minimum_uptime
208
+ instrument_booted_at(expected_booted_at) { uptime }
209
+ b0 = subject.booted_at
210
+ wait_for_tick_change # uptime may use either system data or a relative time
211
+ uptime += 1
212
+ b1 = subject.booted_at
213
+ b0.should == b1
214
+ end
215
+ end # booted_at
216
+ end # supports any platform shell
@@ -0,0 +1,181 @@
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
+ describe RightScale::Platform do
26
+ include PlatformSpecHelper
27
+
28
+ context 'unix/darwin' do
29
+
30
+ # required by before_all_platform_tests
31
+ # called by before(:all) so not defined using let().
32
+ def expected_genus; :unix; end
33
+ def expected_species; :darwin; end
34
+
35
+ before(:all) do
36
+ before_all_platform_tests
37
+ end
38
+
39
+ after(:all) do
40
+ after_all_platform_tests
41
+ end
42
+
43
+ before(:each) do
44
+ before_each_platform_test
45
+ end
46
+
47
+ after(:each) do
48
+ after_each_platform_test
49
+ end
50
+
51
+ context 'statics' do
52
+ subject { platform_class }
53
+
54
+ it 'should be linux' do
55
+ subject.unix?.should be_true
56
+ subject.windows?.should be_false
57
+ subject.linux?.should be_false
58
+ subject.darwin?.should be_true
59
+ end
60
+ end
61
+
62
+ context 'initialization' do
63
+
64
+ let(:sw_vers_cmd) { 'sw_vers -productVersion 2>&1' }
65
+
66
+ context 'when sw_vers is available' do
67
+ it 'should initialize from sw_vers data' do
68
+ platform_instance.
69
+ should_receive(:execute).
70
+ with(sw_vers_cmd).
71
+ and_return("10.8.5\n").
72
+ once
73
+ platform_instance.send(:initialize_species)
74
+ platform_instance.flavor.should == 'mac_os_x'
75
+ platform_instance.release.should == '10.8.5'
76
+ platform_instance.codename.should == ''
77
+ end
78
+ end # when lsb_release is available
79
+
80
+ context 'when sw_vers is not available' do
81
+ it 'should be unknown release' do
82
+ platform_instance.
83
+ should_receive(:execute).
84
+ with(sw_vers_cmd).
85
+ and_raise(described_class::CommandError).
86
+ once
87
+ platform_instance.send(:initialize_species)
88
+ platform_instance.flavor.should == 'mac_os_x'
89
+ platform_instance.release.should == 'unknown'
90
+ platform_instance.codename.should == 'unknown'
91
+ end
92
+ end # when lsb_release is not available
93
+ end # initialization
94
+
95
+ context :controller do
96
+ subject { described_class.controller }
97
+
98
+ context '#reboot' do
99
+ it 'should call shutdown -r now under darwin' do
100
+ platform_class.should_receive(:execute).with('shutdown -r now 2>&1', {}).and_return('')
101
+ subject.reboot.should be_true
102
+ end
103
+ end # reboot
104
+
105
+ context '#shutdown' do
106
+ it 'should call shutdown -h now under darwin' do
107
+ platform_class.should_receive(:execute).with('shutdown -h now 2>&1', {}).and_return('')
108
+ subject.shutdown.should be_true
109
+ end
110
+ end # shutdown
111
+ end # controller
112
+
113
+ context :filesystem do
114
+ subject { described_class.filesystem }
115
+
116
+ it_should_behave_like 'supports unix platform filesystem'
117
+ end
118
+
119
+ context :installer do
120
+ subject { described_class.installer }
121
+
122
+ context :install do
123
+ it 'should raise not implemented' do
124
+ expect { subject.install(%w[foo bar]) }.
125
+ to raise_error(
126
+ ::NotImplementedError, 'Not yet supporting Mac OS package install')
127
+ end
128
+ end # install
129
+ end # installer
130
+
131
+ context :shell do
132
+ subject { described_class.shell }
133
+
134
+ # required by 'supports any platform shell'
135
+ def instrument_booted_at(booted_at)
136
+ time = ::Time.at(booted_at.to_i)
137
+ platform_class.
138
+ should_receive(:execute).
139
+ with('sysctl kern.boottime', {}).
140
+ and_return("kern.boottime: { sec = #{time.to_i}, usec = 0 } #{time.to_s}")
141
+
142
+ # note that uptime is computed relative to boottime.
143
+ true
144
+ end
145
+
146
+ it_should_behave_like 'supports unix platform shell'
147
+ end
148
+
149
+ context :rng do
150
+ subject { described_class.rng }
151
+
152
+ it_should_behave_like 'supports unix platform rng'
153
+ end
154
+
155
+ context :process do
156
+ subject { described_class.process }
157
+
158
+ it_should_behave_like 'supports unix platform process'
159
+ end
160
+
161
+ context :volume_manager do
162
+ subject { platform_class.volume_manager }
163
+
164
+ context :volumes do
165
+ it 'should raise not implemented' do
166
+ expect { subject.volumes }.
167
+ to raise_error(
168
+ ::NotImplementedError, 'Not yet supporting Mac OS volume query')
169
+ end
170
+ end # volumes
171
+
172
+ context :mount_volume do
173
+ it 'should raise not implemented' do
174
+ expect { subject.volumes }.
175
+ to raise_error(
176
+ ::NotImplementedError, 'Not yet supporting Mac OS volume query')
177
+ end
178
+ end # mount_volume
179
+ end # volume_manager
180
+ end # under unix/darwin
181
+ end # RightScale::Platform