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.
- data/LICENSE +20 -0
- data/README.rdoc +82 -0
- data/Rakefile +113 -0
- data/lib/right_agent.rb +59 -0
- data/lib/right_agent/actor.rb +182 -0
- data/lib/right_agent/actor_registry.rb +76 -0
- data/lib/right_agent/actors/agent_manager.rb +232 -0
- data/lib/right_agent/agent.rb +1149 -0
- data/lib/right_agent/agent_config.rb +480 -0
- data/lib/right_agent/agent_identity.rb +210 -0
- data/lib/right_agent/agent_tag_manager.rb +237 -0
- data/lib/right_agent/audit_formatter.rb +107 -0
- data/lib/right_agent/clients.rb +31 -0
- data/lib/right_agent/clients/api_client.rb +383 -0
- data/lib/right_agent/clients/auth_client.rb +247 -0
- data/lib/right_agent/clients/balanced_http_client.rb +369 -0
- data/lib/right_agent/clients/base_retry_client.rb +495 -0
- data/lib/right_agent/clients/right_http_client.rb +279 -0
- data/lib/right_agent/clients/router_client.rb +493 -0
- data/lib/right_agent/command.rb +30 -0
- data/lib/right_agent/command/agent_manager_commands.rb +150 -0
- data/lib/right_agent/command/command_client.rb +136 -0
- data/lib/right_agent/command/command_constants.rb +33 -0
- data/lib/right_agent/command/command_io.rb +126 -0
- data/lib/right_agent/command/command_parser.rb +87 -0
- data/lib/right_agent/command/command_runner.rb +118 -0
- data/lib/right_agent/command/command_serializer.rb +63 -0
- data/lib/right_agent/connectivity_checker.rb +179 -0
- data/lib/right_agent/console.rb +65 -0
- data/lib/right_agent/core_payload_types.rb +44 -0
- data/lib/right_agent/core_payload_types/cookbook.rb +61 -0
- data/lib/right_agent/core_payload_types/cookbook_position.rb +46 -0
- data/lib/right_agent/core_payload_types/cookbook_repository.rb +116 -0
- data/lib/right_agent/core_payload_types/cookbook_sequence.rb +70 -0
- data/lib/right_agent/core_payload_types/dev_repositories.rb +100 -0
- data/lib/right_agent/core_payload_types/dev_repository.rb +76 -0
- data/lib/right_agent/core_payload_types/event_categories.rb +38 -0
- data/lib/right_agent/core_payload_types/executable_bundle.rb +130 -0
- data/lib/right_agent/core_payload_types/login_policy.rb +72 -0
- data/lib/right_agent/core_payload_types/login_user.rb +79 -0
- data/lib/right_agent/core_payload_types/planned_volume.rb +94 -0
- data/lib/right_agent/core_payload_types/recipe_instantiation.rb +73 -0
- data/lib/right_agent/core_payload_types/repositories_bundle.rb +50 -0
- data/lib/right_agent/core_payload_types/right_script_attachment.rb +95 -0
- data/lib/right_agent/core_payload_types/right_script_instantiation.rb +94 -0
- data/lib/right_agent/core_payload_types/runlist_policy.rb +44 -0
- data/lib/right_agent/core_payload_types/secure_document.rb +66 -0
- data/lib/right_agent/core_payload_types/secure_document_location.rb +63 -0
- data/lib/right_agent/core_payload_types/software_repository_instantiation.rb +61 -0
- data/lib/right_agent/daemonize.rb +35 -0
- data/lib/right_agent/dispatched_cache.rb +109 -0
- data/lib/right_agent/dispatcher.rb +272 -0
- data/lib/right_agent/enrollment_result.rb +221 -0
- data/lib/right_agent/exceptions.rb +87 -0
- data/lib/right_agent/history.rb +145 -0
- data/lib/right_agent/log.rb +460 -0
- data/lib/right_agent/minimal.rb +46 -0
- data/lib/right_agent/monkey_patches.rb +30 -0
- data/lib/right_agent/monkey_patches/ruby_patch.rb +55 -0
- data/lib/right_agent/monkey_patches/ruby_patch/array_patch.rb +29 -0
- data/lib/right_agent/monkey_patches/ruby_patch/darwin_patch.rb +24 -0
- data/lib/right_agent/monkey_patches/ruby_patch/linux_patch.rb +24 -0
- data/lib/right_agent/monkey_patches/ruby_patch/linux_patch/file_patch.rb +30 -0
- data/lib/right_agent/monkey_patches/ruby_patch/object_patch.rb +49 -0
- data/lib/right_agent/monkey_patches/ruby_patch/windows_patch.rb +32 -0
- data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/file_patch.rb +60 -0
- data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/process_patch.rb +63 -0
- data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/stdio_patch.rb +27 -0
- data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/time_patch.rb +55 -0
- data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/win32ole_patch.rb +34 -0
- data/lib/right_agent/multiplexer.rb +102 -0
- data/lib/right_agent/offline_handler.rb +270 -0
- data/lib/right_agent/operation_result.rb +300 -0
- data/lib/right_agent/packets.rb +673 -0
- data/lib/right_agent/payload_formatter.rb +104 -0
- data/lib/right_agent/pending_requests.rb +128 -0
- data/lib/right_agent/pid_file.rb +159 -0
- data/lib/right_agent/platform.rb +770 -0
- data/lib/right_agent/platform/unix/darwin/platform.rb +102 -0
- data/lib/right_agent/platform/unix/linux/platform.rb +305 -0
- data/lib/right_agent/platform/unix/platform.rb +226 -0
- data/lib/right_agent/platform/windows/mingw/platform.rb +447 -0
- data/lib/right_agent/platform/windows/mswin/platform.rb +236 -0
- data/lib/right_agent/platform/windows/platform.rb +1808 -0
- data/lib/right_agent/protocol_version_mixin.rb +69 -0
- data/lib/right_agent/retryable_request.rb +195 -0
- data/lib/right_agent/scripts/agent_controller.rb +543 -0
- data/lib/right_agent/scripts/agent_deployer.rb +400 -0
- data/lib/right_agent/scripts/common_parser.rb +160 -0
- data/lib/right_agent/scripts/log_level_manager.rb +192 -0
- data/lib/right_agent/scripts/stats_manager.rb +268 -0
- data/lib/right_agent/scripts/usage.rb +58 -0
- data/lib/right_agent/secure_identity.rb +92 -0
- data/lib/right_agent/security.rb +32 -0
- data/lib/right_agent/security/cached_certificate_store_proxy.rb +77 -0
- data/lib/right_agent/security/certificate.rb +102 -0
- data/lib/right_agent/security/certificate_cache.rb +89 -0
- data/lib/right_agent/security/distinguished_name.rb +56 -0
- data/lib/right_agent/security/encrypted_document.rb +83 -0
- data/lib/right_agent/security/rsa_key_pair.rb +76 -0
- data/lib/right_agent/security/signature.rb +86 -0
- data/lib/right_agent/security/static_certificate_store.rb +85 -0
- data/lib/right_agent/sender.rb +792 -0
- data/lib/right_agent/serialize.rb +29 -0
- data/lib/right_agent/serialize/message_pack.rb +107 -0
- data/lib/right_agent/serialize/secure_serializer.rb +151 -0
- data/lib/right_agent/serialize/secure_serializer_initializer.rb +47 -0
- data/lib/right_agent/serialize/serializable.rb +151 -0
- data/lib/right_agent/serialize/serializer.rb +159 -0
- data/lib/right_agent/subprocess.rb +38 -0
- data/lib/right_agent/tracer.rb +124 -0
- data/right_agent.gemspec +101 -0
- data/spec/actor_registry_spec.rb +80 -0
- data/spec/actor_spec.rb +162 -0
- data/spec/agent_config_spec.rb +235 -0
- data/spec/agent_identity_spec.rb +78 -0
- data/spec/agent_spec.rb +734 -0
- data/spec/agent_tag_manager_spec.rb +319 -0
- data/spec/clients/api_client_spec.rb +423 -0
- data/spec/clients/auth_client_spec.rb +272 -0
- data/spec/clients/balanced_http_client_spec.rb +576 -0
- data/spec/clients/base_retry_client_spec.rb +635 -0
- data/spec/clients/router_client_spec.rb +594 -0
- data/spec/clients/spec_helper.rb +111 -0
- data/spec/command/agent_manager_commands_spec.rb +51 -0
- data/spec/command/command_io_spec.rb +93 -0
- data/spec/command/command_parser_spec.rb +79 -0
- data/spec/command/command_runner_spec.rb +107 -0
- data/spec/command/command_serializer_spec.rb +51 -0
- data/spec/connectivity_checker_spec.rb +83 -0
- data/spec/core_payload_types/dev_repositories_spec.rb +64 -0
- data/spec/core_payload_types/dev_repository_spec.rb +33 -0
- data/spec/core_payload_types/executable_bundle_spec.rb +67 -0
- data/spec/core_payload_types/login_user_spec.rb +102 -0
- data/spec/core_payload_types/recipe_instantiation_spec.rb +81 -0
- data/spec/core_payload_types/right_script_attachment_spec.rb +65 -0
- data/spec/core_payload_types/right_script_instantiation_spec.rb +79 -0
- data/spec/core_payload_types/spec_helper.rb +23 -0
- data/spec/dispatched_cache_spec.rb +136 -0
- data/spec/dispatcher_spec.rb +324 -0
- data/spec/enrollment_result_spec.rb +53 -0
- data/spec/history_spec.rb +246 -0
- data/spec/log_spec.rb +192 -0
- data/spec/monkey_patches/eventmachine_spec.rb +62 -0
- data/spec/multiplexer_spec.rb +48 -0
- data/spec/offline_handler_spec.rb +340 -0
- data/spec/operation_result_spec.rb +208 -0
- data/spec/packets_spec.rb +461 -0
- data/spec/pending_requests_spec.rb +136 -0
- data/spec/platform/spec_helper.rb +216 -0
- data/spec/platform/unix/darwin/platform_spec.rb +181 -0
- data/spec/platform/unix/linux/platform_spec.rb +540 -0
- data/spec/platform/unix/spec_helper.rb +149 -0
- data/spec/platform/windows/mingw/platform_spec.rb +222 -0
- data/spec/platform/windows/mswin/platform_spec.rb +259 -0
- data/spec/platform/windows/spec_helper.rb +720 -0
- data/spec/retryable_request_spec.rb +306 -0
- data/spec/secure_identity_spec.rb +50 -0
- data/spec/security/cached_certificate_store_proxy_spec.rb +62 -0
- data/spec/security/certificate_cache_spec.rb +71 -0
- data/spec/security/certificate_spec.rb +49 -0
- data/spec/security/distinguished_name_spec.rb +46 -0
- data/spec/security/encrypted_document_spec.rb +55 -0
- data/spec/security/rsa_key_pair_spec.rb +55 -0
- data/spec/security/signature_spec.rb +66 -0
- data/spec/security/static_certificate_store_spec.rb +58 -0
- data/spec/sender_spec.rb +1045 -0
- data/spec/serialize/message_pack_spec.rb +131 -0
- data/spec/serialize/secure_serializer_spec.rb +132 -0
- data/spec/serialize/serializable_spec.rb +90 -0
- data/spec/serialize/serializer_spec.rb +197 -0
- data/spec/spec.opts +2 -0
- data/spec/spec.win32.opts +1 -0
- data/spec/spec_helper.rb +130 -0
- data/spec/tracer_spec.rb +114 -0
- 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
|