auser-poolparty 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. data/Manifest.txt +201 -0
  2. data/PostInstall.txt +17 -0
  3. data/Rakefile +22 -1
  4. data/bin/cloud-add-keypair +0 -0
  5. data/bin/cloud-osxcopy +22 -0
  6. data/bin/cloud-provision +1 -0
  7. data/bin/cloud-start +17 -15
  8. data/bin/cloud-terminate +23 -0
  9. data/bin/pool-start +14 -14
  10. data/bin/pool-start-monitor +1 -0
  11. data/config/hoe.rb +114 -0
  12. data/config/requirements.rb +15 -0
  13. data/lib/poolparty.rb +1 -0
  14. data/lib/poolparty/base_packages/haproxy.rb +32 -31
  15. data/lib/poolparty/base_packages/heartbeat.rb +2 -2
  16. data/lib/poolparty/base_packages/poolparty.rb +9 -3
  17. data/lib/poolparty/base_packages/ruby.rb +10 -0
  18. data/lib/poolparty/core/proc.rb +5 -0
  19. data/lib/poolparty/core/string.rb +1 -1
  20. data/lib/poolparty/helpers/binary.rb +6 -5
  21. data/lib/poolparty/helpers/display.rb +11 -2
  22. data/lib/poolparty/helpers/optioner.rb +6 -3
  23. data/lib/poolparty/helpers/provisioner_base.rb +9 -7
  24. data/lib/poolparty/helpers/provisioners/master.rb +38 -4
  25. data/lib/poolparty/helpers/provisioners/slave.rb +2 -2
  26. data/lib/poolparty/modules/cloud_resourcer.rb +20 -3
  27. data/lib/poolparty/modules/definable_resource.rb +1 -1
  28. data/lib/poolparty/modules/method_missing_sugar.rb +12 -4
  29. data/lib/poolparty/modules/pretty_printer.rb +2 -1
  30. data/lib/poolparty/net/remote.rb +1 -1
  31. data/lib/poolparty/net/remote_bases/ec2.rb +13 -10
  32. data/lib/poolparty/net/remote_instance.rb +3 -2
  33. data/lib/poolparty/net/remoter.rb +33 -18
  34. data/lib/poolparty/net/remoter_base.rb +3 -3
  35. data/lib/poolparty/plugins/gem_package.rb +6 -29
  36. data/lib/poolparty/plugins/git.rb +22 -0
  37. data/lib/poolparty/pool/base.rb +7 -6
  38. data/lib/poolparty/pool/cloud.rb +34 -5
  39. data/lib/poolparty/pool/custom_resource.rb +4 -4
  40. data/lib/poolparty/pool/plugin.rb +13 -14
  41. data/lib/poolparty/pool/resource.rb +19 -10
  42. data/lib/poolparty/pool/resources/class_package.rb +10 -6
  43. data/lib/poolparty/pool/resources/conditional.rb +41 -0
  44. data/lib/poolparty/pool/resources/gem.rb +2 -2
  45. data/lib/poolparty/pool/script.rb +25 -2
  46. data/lib/poolparty/templates/haproxy.conf +1 -1
  47. data/lib/poolparty/templates/puppet.conf +4 -2
  48. data/lib/poolparty/version.rb +1 -1
  49. data/poolparty.gemspec +60 -0
  50. data/setup.rb +1585 -0
  51. data/spec/poolparty/base_packages/haproxy_spec.rb +13 -0
  52. data/spec/poolparty/base_packages/heartbeat_spec.rb +30 -0
  53. data/spec/poolparty/bin/console_spec.rb +80 -0
  54. data/spec/poolparty/core/array_spec.rb +26 -0
  55. data/spec/poolparty/core/float.rb +13 -0
  56. data/spec/poolparty/core/hash_spec.rb +63 -0
  57. data/spec/poolparty/core/kernel_spec.rb +24 -0
  58. data/spec/poolparty/core/module_spec.rb +15 -0
  59. data/spec/poolparty/core/object_spec.rb +40 -0
  60. data/spec/poolparty/core/string_spec.rb +152 -0
  61. data/spec/poolparty/core/time_spec.rb +52 -0
  62. data/spec/poolparty/helpers/binary_spec.rb +26 -0
  63. data/spec/poolparty/helpers/display_spec.rb +13 -0
  64. data/spec/poolparty/helpers/optioner_spec.rb +39 -0
  65. data/spec/poolparty/helpers/provisioner_base_spec.rb +121 -0
  66. data/spec/poolparty/helpers/provisioners/master_spec.rb +54 -0
  67. data/spec/poolparty/helpers/provisioners/slave_spec.rb +28 -0
  68. data/spec/poolparty/modules/cloud_resourcer_spec.rb +135 -0
  69. data/spec/poolparty/modules/configurable_spec.rb +26 -0
  70. data/spec/poolparty/modules/definable_resource.rb +9 -0
  71. data/spec/poolparty/modules/file_writer_spec.rb +49 -0
  72. data/spec/poolparty/modules/s3_string_spec.rb +15 -0
  73. data/spec/poolparty/net/remote_bases/ec2_spec.rb +92 -0
  74. data/spec/poolparty/net/remote_instance_spec.rb +70 -0
  75. data/spec/poolparty/net/remote_spec.rb +286 -0
  76. data/spec/poolparty/net/remoter_base_spec.rb +80 -0
  77. data/spec/poolparty/net/remoter_spec.rb +191 -0
  78. data/spec/poolparty/plugins/git_spec.rb +19 -0
  79. data/spec/poolparty/plugins/line_spec.rb +16 -0
  80. data/spec/poolparty/plugins/svn_spec.rb +16 -0
  81. data/spec/poolparty/pool/base_spec.rb +108 -0
  82. data/spec/poolparty/pool/cloud_spec.rb +299 -0
  83. data/spec/poolparty/pool/configurers/files/ruby_basic.rb +17 -0
  84. data/spec/poolparty/pool/configurers/files/ruby_plugins.rb +16 -0
  85. data/spec/poolparty/pool/configurers/ruby_spec.rb +58 -0
  86. data/spec/poolparty/pool/custom_resource_spec.rb +115 -0
  87. data/spec/poolparty/pool/example_spec.rb +112 -0
  88. data/spec/poolparty/pool/plugin_model_spec.rb +63 -0
  89. data/spec/poolparty/pool/plugin_spec.rb +85 -0
  90. data/spec/poolparty/pool/pool_spec.rb +83 -0
  91. data/spec/poolparty/pool/resource_spec.rb +224 -0
  92. data/spec/poolparty/pool/resources/class_package_spec.rb +84 -0
  93. data/spec/poolparty/pool/resources/conditional_spec.rb +38 -0
  94. data/spec/poolparty/pool/resources/cron_spec.rb +49 -0
  95. data/spec/poolparty/pool/resources/directory_spec.rb +40 -0
  96. data/spec/poolparty/pool/resources/exec_spec.rb +37 -0
  97. data/spec/poolparty/pool/resources/file_spec.rb +40 -0
  98. data/spec/poolparty/pool/resources/gem_spec.rb +16 -0
  99. data/spec/poolparty/pool/resources/host_spec.rb +28 -0
  100. data/spec/poolparty/pool/resources/package_spec.rb +44 -0
  101. data/spec/poolparty/pool/resources/remote_file_spec.rb +40 -0
  102. data/spec/poolparty/pool/resources/service_spec.rb +45 -0
  103. data/spec/poolparty/pool/resources/sshkey_spec.rb +48 -0
  104. data/spec/poolparty/pool/resources/variable_spec.rb +20 -0
  105. data/spec/poolparty/pool/script_spec.rb +51 -0
  106. data/spec/poolparty/pool/test_plugins/sshkey_test +2 -0
  107. data/spec/poolparty/pool/test_plugins/virtual_host_template.erb +0 -0
  108. data/spec/poolparty/pool/test_plugins/webserver.rb +46 -0
  109. data/spec/poolparty/poolparty_spec.rb +33 -0
  110. data/spec/poolparty/spec_helper.rb +120 -0
  111. data/test/test_generator_helper.rb +29 -0
  112. data/test/test_helper.rb +2 -0
  113. data/test/test_pool_spec_generator.rb +47 -0
  114. data/test/test_poolparty.rb +11 -0
  115. data/website/index.html +81 -0
  116. data/website/index.txt +72 -0
  117. data/website/javascripts/rounded_corners_lite.inc.js +285 -0
  118. data/website/stylesheets/screen.css +138 -0
  119. data/website/template.html.erb +48 -0
  120. metadata +178 -60
@@ -0,0 +1,26 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ class TestClass
4
+ include Configurable
5
+ end
6
+
7
+ describe "configurable" do
8
+ before(:each) do
9
+ @tc = TestClass.new
10
+ end
11
+ it "should set the name as frank" do
12
+ @tc.name.should == nil
13
+ @tc.configure({:name => "frank"})
14
+ @tc.name.should == "frank"
15
+ end
16
+ it "should reset the name after it's been set" do
17
+ @tc.configure({:name => "frank"})
18
+ @tc.configure({:name => "timmy"})
19
+ @tc.name.should == "timmy"
20
+ end
21
+ it "should be able to reconfigure itself" do
22
+ @tc.configure(:name => "walter")
23
+ @tc.reconfigure(:name => "dewey")
24
+ @tc.name.should == "dewey"
25
+ end
26
+ end
@@ -0,0 +1,9 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ include PoolParty::DefinableResource
4
+
5
+ describe "define_resource" do
6
+ it "should have the method define_resource available" do
7
+ self.respond_to?(:define_resource).should == true
8
+ end
9
+ end
@@ -0,0 +1,49 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ class TestClass
4
+ include FileWriter
5
+ end
6
+ describe "FileWriter" do
7
+ before(:each) do
8
+ @test = TestClass.new
9
+ @filepath = File.join("nilly.rb")
10
+ @path = File.join(Base.storage_directory, @filepath)
11
+ end
12
+ %w(write_to_file_in_storage_directory copy_file_to_storage_directory write_to_temp_file).each do |method|
13
+ eval <<-EOE
14
+ it "should have a #{method} method" do
15
+ @test.respond_to?(:#{method}).should == true
16
+ end
17
+ EOE
18
+ end
19
+ it "should copy the file to the Base.storage_directory when calling copy_file_to_storage_directory" do
20
+ FileUtils.should_receive(:cp).with("ranger", Base.storage_directory+"/ranger").and_return true
21
+ @test.copy_file_to_storage_directory("ranger")
22
+ end
23
+ describe "write to file in storage directory" do
24
+ it "should try to create the directory if it doesn't exist" do
25
+ FileTest.stub!(:directory?).and_return false
26
+ ::File.stub!(:open).and_return true
27
+ FileUtils.should_receive(:mkdir_p).with(::File.dirname(@path))
28
+ end
29
+ it "should call File.open on the file" do
30
+ ::File.should_receive(:open).with(@path, "w+").and_return true
31
+ end
32
+ it "should call the block if it is given with a block" do
33
+ block = Proc.new do |a|
34
+ "meee: #{a.class}"
35
+ end
36
+ @test.write_to_file_in_storage_directory(@filepath, "STRING TO WRITE", &block)
37
+ end
38
+ it "should write the string in the file" do
39
+ @test.write_to_file_in_storage_directory(@filepath, "STRING TO WRITE")
40
+ open(::File.join( Base.storage_directory, @filepath)).read.should == "STRING TO WRITE"
41
+ end
42
+ after do
43
+ @test.write_to_file_in_storage_directory(@filepath, "STRING TO WRITE")
44
+ end
45
+ end
46
+ after(:all) do
47
+ ::File.unlink @path if ::File.file? @path
48
+ end
49
+ end
@@ -0,0 +1,15 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe "S3 String" do
4
+ before(:each) do
5
+ @str = "testbucketstring"
6
+ end
7
+ %w(bucket_objects bucket_object bucket_object_exists?
8
+ store_bucket_value delete_bucket_value bucket_exists? delete_bucket).each do |meth|
9
+ eval <<-EOE
10
+ it "should have the method #{meth}" do
11
+ @str.respond_to?(:#{meth}).should == true
12
+ end
13
+ EOE
14
+ end
15
+ end
@@ -0,0 +1,92 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ include Remote
4
+
5
+ class TestClass
6
+ include RemoterBase
7
+ include Ec2
8
+ include CloudResourcer
9
+
10
+ def keypair
11
+ "fake_keypair"
12
+ end
13
+
14
+ def ami;"ami-abc123";end
15
+ def size; "small";end
16
+
17
+ def ec2
18
+ @ec2 ||= EC2::Base.new( :access_key_id => "not_an_access_key", :secret_access_key => "not_a_secret_access_key")
19
+ end
20
+ end
21
+ describe "ec2 remote base" do
22
+ before(:each) do
23
+ @tr = TestClass.new
24
+ stub_remoter_for(@tr)
25
+ @tr.stub!(:get_instances_description).and_return response_list_of_instances
26
+ end
27
+ %w(launch_new_instance! terminate_instance! describe_instance describe_instances).each do |method|
28
+ eval <<-EOE
29
+ it "should have the method #{method}" do
30
+ @tr.respond_to?(:#{method}).should == true
31
+ end
32
+ EOE
33
+ end
34
+ describe "launching" do
35
+ before(:each) do
36
+ @tr.ec2.stub!(:run_instances).and_return true
37
+ end
38
+ it "should call run_instances on the ec2 Base class when asking to launch_new_instance!" do
39
+ @tr.ec2.should_receive(:run_instances).and_return true
40
+ @tr.launch_new_instance!
41
+ end
42
+ it "should get the hash response from EC2ResponseObject" do
43
+ EC2ResponseObject.should_receive(:get_hash_from_response).with(true).and_return true
44
+ @tr.launch_new_instance!
45
+ end
46
+ end
47
+ describe "terminating" do
48
+ it "should call terminate_instance! on ec2 when asking to terminate_instance!" do
49
+ @tr.ec2.should_receive(:terminate_instances).with(:instance_id => "abc-123").and_return true
50
+ @tr.terminate_instance!("abc-123")
51
+ end
52
+ end
53
+ describe "describe_instance" do
54
+ it "should call get_instances_description on itself" do
55
+ @tr.should_receive(:get_instances_description).and_return {}
56
+ @tr.describe_instance
57
+ end
58
+ end
59
+ describe "get_instances_description" do
60
+ it "should return a hash" do
61
+ @tr.describe_instances.class.should == Array
62
+ end
63
+ it "should call the first node master" do
64
+ @tr.describe_instances.first[:name].should == "master"
65
+ end
66
+ it "should call the second one node1" do
67
+ @tr.describe_instances[1][:name].should == "node1"
68
+ end
69
+ it "should call the third node2" do
70
+ @tr.describe_instances[2][:name].should == "terminated_node2"
71
+ end
72
+ end
73
+ describe "create_keypair" do
74
+ before(:each) do
75
+ Kernel.stub!(:system).with("ec2-add-keypair fake_keypair > #{Base.base_keypair_path}/id_rsa-fake_keypair && chmod 600 #{Base.base_keypair_path}/id_rsa-fake_keypair").and_return true
76
+ end
77
+ it "should send system to the Kernel" do
78
+ Kernel.should_receive(:system).with("ec2-add-keypair fake_keypair > #{Base.base_keypair_path}/id_rsa-fake_keypair && chmod 600 #{Base.base_keypair_path}/id_rsa-fake_keypair").and_return true
79
+ @tr.create_keypair
80
+ end
81
+ it "should try to create the directory when making a new keypair" do
82
+ FileUtils.should_receive(:mkdir_p).and_return true
83
+ ::File.stub!(:directory?).and_return false
84
+ @tr.create_keypair
85
+ end
86
+ it "should not create a keypair if the keypair is nil" do
87
+ Kernel.should_not_receive(:system)
88
+ @tr.stub!(:keypair).and_return nil
89
+ @tr.create_keypair
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,70 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ include Remote
4
+
5
+ describe "Remote Instance" do
6
+ before(:each) do
7
+ @valid_hash = {:ip => "127.0.0.1", :name => "master", :responding => "true"}
8
+ end
9
+ describe "configurable" do
10
+ it "should set the options sent in the options" do
11
+ @ri = RemoteInstance.new(@valid_hash, nil)
12
+ @ri.ip.should == "127.0.0.1"
13
+ end
14
+ it "should set the options sent by the parent" do
15
+ @obj = Object.new
16
+ @obj.stub!(:options).and_return({:dude => "tte"})
17
+ @ri = RemoteInstance.new(@valid_hash, @obj)
18
+ @ri.dude.should == "tte"
19
+ end
20
+ it "should not overwrite the options that are already set" do
21
+ @obj = Object.new
22
+ @obj.stub!(:options).and_return({:ip => "172.176.0.1"})
23
+ @ri = RemoteInstance.new(@valid_hash, @obj)
24
+ @ri.ip.should == "127.0.0.1"
25
+ end
26
+ end
27
+ it "should create a remote instance with a Hash" do
28
+ @ri = RemoteInstance.new(@valid_hash, nil)
29
+ @ri.valid?.should == true
30
+ end
31
+ it "should not be valid if there is no ip associated" do
32
+ @ri = RemoteInstance.new(@valid_hash.merge({:ip => nil}), nil)
33
+ @ri.valid?.should == false
34
+ end
35
+ it "should not be valid if there is no name associated" do
36
+ @ri = RemoteInstance.new(@valid_hash.merge({:name => nil}), nil)
37
+ @ri.valid?.should == false
38
+ end
39
+ describe "status" do
40
+ it "should say it is running when the status == running" do
41
+ RemoteInstance.new(@valid_hash.merge(:status => "running")).running?.should == true
42
+ end
43
+ it "should say it is pending when the status == pending" do
44
+ RemoteInstance.new(@valid_hash.merge(:status => "pending")).pending?.should == true
45
+ end
46
+ it "should say it is terminating when the status == shutting down" do
47
+ RemoteInstance.new(@valid_hash.merge(:status => "shutting down")).terminating?.should == true
48
+ end
49
+ it "should say it is terminated when the status == terminated" do
50
+ RemoteInstance.new(@valid_hash.merge(:status => "terminated")).terminated?.should == true
51
+ end
52
+ it "should not say it is running when it is pending" do
53
+ RemoteInstance.new(@valid_hash.merge(:status => "pending"), nil).running?.should == false
54
+ end
55
+ end
56
+ describe "methods" do
57
+ before(:each) do
58
+ @ri = RemoteInstance.new(@valid_hash, nil)
59
+ end
60
+ it "should be say that it is the master if the name is master" do
61
+ @ri.name.should == "master"
62
+ @ri.master?.should == true
63
+ end
64
+ it "should say that it is responding? if responding is not nil" do
65
+ @ri.responding.should_not be_nil
66
+ @ri.responding?.should == true
67
+ end
68
+
69
+ end
70
+ end
@@ -0,0 +1,286 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ require "ftools"
3
+
4
+ module Hype
5
+ def hyper
6
+ "beatnick"
7
+ end
8
+ def instances_list
9
+ []
10
+ end
11
+ register_remote_base :Hype
12
+ end
13
+ class TestClass
14
+ include Remote
15
+
16
+ def keypair
17
+ "fake_keypair"
18
+ end
19
+ end
20
+
21
+ describe "Remote" do
22
+ before(:each) do
23
+ @tc = TestClass.new
24
+
25
+ end
26
+ it "should have the method 'using'" do
27
+ @tc.respond_to?(:using).should == true
28
+ end
29
+ it "should include the module with using" do
30
+ @tc.should_receive(:extend).with("Hype".preserved_module_constant).once
31
+ @tc.using :hype
32
+ end
33
+ it "should keep a list of the remote_bases" do
34
+ @tc.stub!(:remote_bases).and_return [:ec2, :hype]
35
+ @tc.available_bases.should == [:ec2, :hype]
36
+ end
37
+ it "should be able to register a new base" do
38
+ @tc.remote_bases.should_receive(:<<).with(:hockey).and_return true
39
+ @tc.register_remote_base("Hockey")
40
+ end
41
+ it "should not extend the module if the remote base isn't found" do
42
+ @tc.should_not_receive(:extend)
43
+ hide_output do
44
+ @tc.using :paper
45
+ end
46
+ end
47
+ describe "when including" do
48
+ it "should be able to say if it is using a remote base with using_remoter?" do
49
+ @tc.using :hype
50
+ @tc.using_remoter?.should_not == nil
51
+ end
52
+ it "should ask if it is using_remoter? when calling using" do
53
+ @tc.should_receive(:using_remoter?).once
54
+ @tc.using :hype
55
+ end
56
+ it "should only include the remote class once" do
57
+ @tc.should_receive(:extend).with(Hype).once
58
+ @tc.using :hype
59
+ @tc.using :hype
60
+ @tc.using :hype
61
+ end
62
+ end
63
+ describe "after using" do
64
+ before(:each) do
65
+ @tc = TestClass.new
66
+ stub_list_from_remote_for(@tc, false)
67
+ @tc.using :hype
68
+ end
69
+ it "should now have the methods available from the module" do
70
+ @tc.respond_to?(:hyper).should == true
71
+ end
72
+ it "should raise an exception because the launch_new_instance! is not defined" do
73
+ lambda {
74
+ @tc.launch_new_instance!
75
+ }.should raise_error
76
+ end
77
+ it "should not raise an exception because instances_list is defined" do
78
+ lambda {
79
+ @tc.remote_instances_list
80
+ }.should_not raise_error
81
+ end
82
+ it "should run hyper" do
83
+ @tc.hyper.should == "beatnick"
84
+ end
85
+ end
86
+ describe "methods" do
87
+ before(:each) do
88
+ @tc = TestClass.new
89
+ @tc.using :ec2
90
+
91
+ @tc.reset!
92
+ @tc.stub!(:minimum_instances).and_return 3
93
+ @tc.stub!(:maximum_instances).and_return 5
94
+
95
+ stub_list_from_remote_for(@tc)
96
+ stub_list_of_instances_for(@tc)
97
+ end
98
+ describe "minimum_number_of_instances_are_running?" do
99
+ it "should be false if there aren't" do
100
+ @tc.minimum_number_of_instances_are_running?.should == false
101
+ end
102
+ it "should be true if there are" do
103
+ add_stub_instance_to(@tc, 8)
104
+ @tc.minimum_number_of_instances_are_running?.should == true
105
+ end
106
+ end
107
+ describe "can_shutdown_an_instance?" do
108
+ it "should say false because minimum instances are not running" do
109
+ @tc.can_shutdown_an_instance?.should == false
110
+ end
111
+ it "should say we false if only the minimum instances are running" do
112
+ add_stub_instance_to(@tc, 8)
113
+ @tc.can_shutdown_an_instance?.should == false
114
+ end
115
+ it "should say true because the minimum instances + 1 are running" do
116
+ add_stub_instance_to(@tc, 8)
117
+ add_stub_instance_to(@tc, 9)
118
+ @tc.can_shutdown_an_instance?.should == true
119
+ end
120
+ end
121
+ describe "request_launch_new_instances" do
122
+ it "should requiest to launch a new instance 3 times" do
123
+ @tc.should_receive(:launch_new_instance!).exactly(3).and_return "launched"
124
+ @tc.request_launch_new_instances(3)
125
+ end
126
+ it "should return a list of hashes" do
127
+ @tc.should_receive(:launch_new_instance!).exactly(3).and_return({:instance_id => "i-dasfasdf"})
128
+ @tc.request_launch_new_instances(3).first.class.should == Hash
129
+ end
130
+ end
131
+ describe "can_start_a_new_instance?" do
132
+ it "should be true because the maximum instances are not running" do
133
+ @tc.can_start_a_new_instance?.should == true
134
+ end
135
+ it "should say that we cannot start a new instance because we are at the maximum instances" do
136
+ add_stub_instance_to(@tc, 7)
137
+ add_stub_instance_to(@tc, 8)
138
+ add_stub_instance_to(@tc, 9)
139
+ @tc.can_start_a_new_instance?.should == false
140
+ end
141
+ end
142
+ describe "maximum_number_of_instances_are_not_running?" do
143
+ it "should be true because the maximum are not running" do
144
+ @tc.maximum_number_of_instances_are_not_running?.should == true
145
+ end
146
+ it "should be false because the maximum are running" do
147
+ add_stub_instance_to(@tc, 7)
148
+ add_stub_instance_to(@tc, 8)
149
+ add_stub_instance_to(@tc, 9)
150
+ @tc.maximum_number_of_instances_are_not_running?.should == false
151
+ end
152
+ end
153
+ describe "request_launch_one_instance_at_a_time" do
154
+ before(:each) do
155
+ @tc.stub!(:wait).and_return "true"
156
+ remove_stub_instance_from(@tc, 3)
157
+ remove_stub_instance_from(@tc, 5)
158
+ @tc.stub!(:launch_new_instance!).and_return {}
159
+ end
160
+ it "should call reset! once" do
161
+ @tc.should_receive(:reset!).once
162
+ @tc.request_launch_one_instance_at_a_time
163
+ end
164
+ it "should not call wait if there are no pending instances" do
165
+ Kernel.should_not_receive(:sleep)
166
+ @tc.request_launch_one_instance_at_a_time
167
+ end
168
+ # TODO: Stub methods with wait
169
+ end
170
+ describe "launch_minimum_number_of_instances" do
171
+ it "should not call minimum_number_of_instances_are_running? if if cannot start a new instance" do
172
+ @tc.stub!(:can_start_a_new_instance?).and_return false
173
+ @tc.should_not_receive(:minimum_number_of_instances_are_running?)
174
+ @tc.launch_minimum_number_of_instances
175
+ end
176
+ # TODO: Stub methods with wait
177
+ end
178
+ describe "request_termination_of_non_master_instance" do
179
+ it "should reject the master instance from the list of instances (we should never shut down the master unless shutting down the cloud)" do
180
+ @master = @tc.list_of_running_instances.select {|a| a.master? }.first
181
+ @tc.should_not_receive(:terminate_instance!).with(@master).and_return true
182
+ @tc.request_termination_of_non_master_instance
183
+ end
184
+ it "should call terminate on an instance" do
185
+ @tc.should_receive(:terminate_instance!).once
186
+ @tc.request_termination_of_non_master_instance
187
+ end
188
+ end
189
+ describe "should_expand_cloud?" do
190
+ end
191
+ describe "should_contract_cloud?" do
192
+ end
193
+ describe "expand_cloud_if_necessary" do
194
+ before(:each) do
195
+ stub_list_from_remote_for(@tc)
196
+ @tc.stub!(:request_launch_new_instances).and_return true
197
+ @tc.stub!(:can_start_a_new_instance).and_return true
198
+ @tc.stub!(:list_of_pending_instances).and_return []
199
+ @tc.stub!(:prepare_to_configuration).and_return true
200
+ @tc.stub!(:build_and_store_new_config_file).and_return true
201
+ end
202
+ it "should receive can_start_a_new_instance?" do
203
+ @tc.should_receive(:can_start_a_new_instance?).once
204
+ end
205
+ it "should see if we should expand the cloud" do
206
+ @tc.should_receive(:should_expand_cloud?).once.and_return false
207
+ end
208
+ it "should call request_launch_new_instances if we should_expand_cloud?" do
209
+ @tc.should_receive(:should_expand_cloud?).once.and_return true
210
+ @tc.should_receive(:request_launch_new_instances).once.and_return [{:ip => "127.0.0.5", :name => "node2"}]
211
+ end
212
+ it "should call a new slave provisioner" do
213
+ @tc.stub!(:should_expand_cloud?).once.and_return true
214
+ @tc.stub!(:request_launch_new_instances).once.and_return [{:ip => "127.0.0.5", :name => "node2"}]
215
+ PoolParty::Provisioner.should_receive(:provision_slave).and_return true
216
+ end
217
+ after(:each) do
218
+ @tc.expand_cloud_if_necessary
219
+ end
220
+ end
221
+ describe "contract_cloud_if_necessary" do
222
+ before(:each) do
223
+ @tc.stub!(:request_termination_of_non_master_instance).and_return true
224
+ @tc.stub!(:can_shutdown_an_instance?).and_return true
225
+ end
226
+ it "should receive can_shutdown_an_instance?" do
227
+ @tc.should_receive(:can_shutdown_an_instance?).once
228
+ end
229
+ it "should see if we should contract the cloud" do
230
+ @tc.should_receive(:should_contract_cloud?).once.and_return false
231
+ end
232
+ it "should call request_termination_of_non_master_instance if we should_contract_cloud?" do
233
+ @tc.should_receive(:should_contract_cloud?).once.and_return true
234
+ @tc.should_receive(:request_termination_of_non_master_instance).once.and_return true
235
+ end
236
+ after(:each) do
237
+ @tc.contract_cloud_if_necessary
238
+ end
239
+ end
240
+ describe "rsync_storage_files_to" do
241
+ before(:each) do
242
+ Kernel.stub!(:system).and_return true
243
+ @tc.extend CloudResourcer
244
+ @tc.stub!(:keypair_path).and_return "~/.ec2/fake_keypair"
245
+ @obj = Object.new
246
+ @obj.stub!(:ip).and_return "192.168.0.1"
247
+ end
248
+ it "should raise an exception if it cannot find the keypair" do
249
+ @tc.stub!(:keypair_path).and_return nil
250
+ lambda {
251
+ @tc.rsync_storage_files_to(@tc.master)
252
+ }.should raise_error
253
+ end
254
+ it "should call exec on the kernel" do
255
+ @tc.stub!(:keypair).and_return "funky"
256
+ ::File.stub!(:exists?).with("#{File.expand_path(Base.base_keypair_path)}/id_rsa-funky").and_return true
257
+ lambda {
258
+ @tc.rsync_storage_files_to(@tc.master)
259
+ }.should_not raise_error
260
+ end
261
+ describe "run_command_on" do
262
+ before(:each) do
263
+ @tc.stub!(:keypair).and_return "fake_keypair"
264
+ @tc.stub!(:keypair_path).and_return "~/.ec2/fake_keypair"
265
+ end
266
+ it "should call system on the kernel" do
267
+ ::File.stub!(:exists?).with("#{File.expand_path(Base.base_keypair_path)}/id_rsa-funky").and_return true
268
+ Kernel.should_receive(:system).with("#{@tc.ssh_string} 192.168.0.1 'ls'").and_return true
269
+ @tc.run_command_on("ls", @obj)
270
+ end
271
+ end
272
+ describe "ssh_into_instance_number" do
273
+ before(:each) do
274
+ @tc.stub!(:keypair).and_return "fake_keypair"
275
+ ::File.stub!(:exists?).with("#{File.expand_path(Base.base_keypair_path)}/id_rsa-funky").and_return true
276
+
277
+ Kernel.stub!(:system).with("#{@tc.ssh_string} 192.168.0.1").and_return true
278
+ end
279
+ it "should find the instance" do
280
+ @tc.should_receive(:get_instance_by_number).with(0).and_return @obj
281
+ @tc.ssh_into_instance_number
282
+ end
283
+ end
284
+ end
285
+ end
286
+ end