tengine_resource 0.5.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. data/.document +5 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +30 -0
  4. data/Gemfile.lock +106 -0
  5. data/README.rdoc +20 -0
  6. data/Rakefile +42 -0
  7. data/VERSION +1 -0
  8. data/bin/tengine_resource_watchd +8 -0
  9. data/config/.gitignore +2 -0
  10. data/config/watchd.yml.erb.example +52 -0
  11. data/lib/tengine/resource.rb +29 -0
  12. data/lib/tengine/resource/config.rb +6 -0
  13. data/lib/tengine/resource/config/resource.rb +194 -0
  14. data/lib/tengine/resource/credential.rb +156 -0
  15. data/lib/tengine/resource/credential/ec2.rb +5 -0
  16. data/lib/tengine/resource/credential/ec2/dummy.rb +148 -0
  17. data/lib/tengine/resource/credential/ec2/launch_options.rb +179 -0
  18. data/lib/tengine/resource/drivers/resource_control_driver.rb +58 -0
  19. data/lib/tengine/resource/net_ssh.rb +134 -0
  20. data/lib/tengine/resource/observer.rb +25 -0
  21. data/lib/tengine/resource/physical_server.rb +7 -0
  22. data/lib/tengine/resource/provider.rb +82 -0
  23. data/lib/tengine/resource/provider/ec2.rb +187 -0
  24. data/lib/tengine/resource/provider/wakame.rb +615 -0
  25. data/lib/tengine/resource/server.rb +62 -0
  26. data/lib/tengine/resource/virtual_server.rb +62 -0
  27. data/lib/tengine/resource/virtual_server_image.rb +34 -0
  28. data/lib/tengine/resource/virtual_server_type.rb +21 -0
  29. data/lib/tengine/resource/watcher.rb +121 -0
  30. data/lib/tengine_resource.rb +4 -0
  31. data/spec/fixtures/goku_at_ec2_ap_northeast.rb +177 -0
  32. data/spec/mongoid.yml +35 -0
  33. data/spec/spec_helper.rb +40 -0
  34. data/spec/support/ec2.rb +129 -0
  35. data/spec/support/mongo_index_key_log.rb +91 -0
  36. data/spec/tengine/resource/bugfix/watcher_for_wakame_spec.rb +232 -0
  37. data/spec/tengine/resource/credential_spec.rb +205 -0
  38. data/spec/tengine/resource/drivers/resource_control_driver_spec.rb +84 -0
  39. data/spec/tengine/resource/net_ssh_spec.rb +148 -0
  40. data/spec/tengine/resource/physical_server_spec.rb +47 -0
  41. data/spec/tengine/resource/provider/ec2_spec.rb +473 -0
  42. data/spec/tengine/resource/provider/test_files/describe_host_nodes.json +22 -0
  43. data/spec/tengine/resource/provider/test_files/describe_images.json +23 -0
  44. data/spec/tengine/resource/provider/test_files/describe_instance_specs.json +23 -0
  45. data/spec/tengine/resource/provider/test_files/describe_instances.json +56 -0
  46. data/spec/tengine/resource/provider/test_files/run_instances.json +30 -0
  47. data/spec/tengine/resource/provider/test_files/terminate_instances.json +3 -0
  48. data/spec/tengine/resource/provider/wakame/00_describe_host_nodes_0_physical_servers.json +8 -0
  49. data/spec/tengine/resource/provider/wakame/01_describe_host_nodes_10_physical_servers.json +139 -0
  50. data/spec/tengine/resource/provider/wakame/02_describe_host_nodes_60_physical_servers.json +795 -0
  51. data/spec/tengine/resource/provider/wakame/10_describe_instances_0_virtual_servers.json +8 -0
  52. data/spec/tengine/resource/provider/wakame/11_describe_instances_10_virtual_servers.json +469 -0
  53. data/spec/tengine/resource/provider/wakame/12_describe_instances_after_run_instances.json +280 -0
  54. data/spec/tengine/resource/provider/wakame/13_describe_instances_after_terminate_instances.json +279 -0
  55. data/spec/tengine/resource/provider/wakame/20_describe_images_0_virtual_server_images.json +8 -0
  56. data/spec/tengine/resource/provider/wakame/21_describe_images_5_virtual_server_images.json +84 -0
  57. data/spec/tengine/resource/provider/wakame/22_describe_images_60_virtual_server_images.json +856 -0
  58. data/spec/tengine/resource/provider/wakame/30_describe_instance_specs_0_virtual_server_specs.json +8 -0
  59. data/spec/tengine/resource/provider/wakame/31_describe_instance_specs_4_virtual_server_specs.json +66 -0
  60. data/spec/tengine/resource/provider/wakame/40_run_instances_0_virtual_servers.json +1 -0
  61. data/spec/tengine/resource/provider/wakame/41_run_instances_1_virtual_servers.json +22 -0
  62. data/spec/tengine/resource/provider/wakame/42_run_instances_5_virtual_servers.json +106 -0
  63. data/spec/tengine/resource/provider/wakame/50_terminate_instances_0_virtual_servers.json +1 -0
  64. data/spec/tengine/resource/provider/wakame/51_terminate_instances_3_virtual_servers.json +5 -0
  65. data/spec/tengine/resource/provider/wakame/sync_physical_servers_spec.rb +114 -0
  66. data/spec/tengine/resource/provider/wakame/sync_virtual_server_images_spec.rb +116 -0
  67. data/spec/tengine/resource/provider/wakame/sync_virtual_server_types_spec.rb +116 -0
  68. data/spec/tengine/resource/provider/wakame/sync_virtual_servers_spec.rb +216 -0
  69. data/spec/tengine/resource/provider/wakame_api_spec.rb +319 -0
  70. data/spec/tengine/resource/provider/wakame_spec.rb +339 -0
  71. data/spec/tengine/resource/provider_spec.rb +252 -0
  72. data/spec/tengine/resource/server_spec.rb +195 -0
  73. data/spec/tengine/resource/test_files/.gitignore +6 -0
  74. data/spec/tengine/resource/test_files/00_describe_host_nodes_0_physical_servers.json +8 -0
  75. data/spec/tengine/resource/test_files/01_describe_host_nodes_10_physical_servers.json +139 -0
  76. data/spec/tengine/resource/test_files/02_describe_host_nodes_60_physical_servers.json +795 -0
  77. data/spec/tengine/resource/test_files/10_describe_instances_0_virtual_servers.json +8 -0
  78. data/spec/tengine/resource/test_files/11_describe_instances_10_virtual_servers.json +469 -0
  79. data/spec/tengine/resource/test_files/12_describe_instances_after_run_instances.json +280 -0
  80. data/spec/tengine/resource/test_files/13_describe_instances_after_terminate_instances.json +279 -0
  81. data/spec/tengine/resource/test_files/14_describe_instances_after_run_1_instance.json +55 -0
  82. data/spec/tengine/resource/test_files/20_describe_images_0_virtual_server_images.json +8 -0
  83. data/spec/tengine/resource/test_files/21_describe_images_5_virtual_server_images.json +84 -0
  84. data/spec/tengine/resource/test_files/22_describe_images_60_virtual_server_images.json +856 -0
  85. data/spec/tengine/resource/test_files/30_describe_instance_specs_0_virtual_server_specs.json +8 -0
  86. data/spec/tengine/resource/test_files/31_describe_instance_specs_4_virtual_server_specs.json +66 -0
  87. data/spec/tengine/resource/test_files/40_run_instances_0_virtual_servers.json +1 -0
  88. data/spec/tengine/resource/test_files/41_run_instances_1_virtual_servers.json +22 -0
  89. data/spec/tengine/resource/test_files/42_run_instances_5_virtual_servers.json +106 -0
  90. data/spec/tengine/resource/test_files/43_run_instances_1_virtual_servers_without_aws_availability_zone.json +22 -0
  91. data/spec/tengine/resource/test_files/50_terminate_instances_0_virtual_servers.json +1 -0
  92. data/spec/tengine/resource/test_files/51_terminate_instances_3_virtual_servers.json +5 -0
  93. data/spec/tengine/resource/virtual_server_image_spec.rb +94 -0
  94. data/spec/tengine/resource/virtual_server_spec.rb +116 -0
  95. data/spec/tengine/resource/virtual_server_type_spec.rb +4 -0
  96. data/spec/tengine/resource/watcher_spec.rb +1026 -0
  97. data/spec/tengine_resource_spec.rb +5 -0
  98. data/tengine_resource.gemspec +171 -0
  99. data/tmp/log/.gitignore +1 -0
  100. metadata +286 -0
@@ -0,0 +1,339 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+ require 'apis/ec2'
4
+ require 'apis/wakame'
5
+ require 'controllers/controller'
6
+
7
+ describe Tengine::Resource::Provider::Wakame do
8
+ subject {
9
+ Tengine::Resource::Provider::Wakame.delete_all(:name => 'tama0001')
10
+ Tengine::Resource::Provider::Wakame.create(
11
+ :name => "tama0001",
12
+ :description => "provided by wakame / tama",
13
+ :connection_settings => {
14
+ :account => "a-shpoolxx",
15
+ :ec2_host => "10.10.10.10",
16
+ :ec2_port => 8000,
17
+ :ec2_protocol => "http",
18
+ :wakame_host => "192.168.2.22",
19
+ :wakame_port => 9001,
20
+ :wakame_protocol => "https",
21
+ },
22
+ )
23
+ }
24
+
25
+ context "API接続" do
26
+ it "コネクションが生成できる" do
27
+ expect {
28
+ invoke_ok = false
29
+ subject.connect do |conn|
30
+ invoke_ok = true
31
+ end
32
+ invoke_ok.should be_true
33
+ }.to_not raise_error
34
+ end
35
+
36
+ it "コネクションの接続でエラーが発生してもリトライできる" do
37
+ subject.retry_on_error = true
38
+ expect {
39
+ invoke_ok = false
40
+ subject.connect do |conn|
41
+ unless invoke_ok
42
+ invoke_ok = true
43
+ raise Errno::ETIMEDOUT
44
+ end
45
+ end
46
+ invoke_ok.should be_true
47
+ }.to_not raise_error
48
+ end
49
+
50
+ it "コネクションの接続でエラーが一定回数発生する場合にはエラーにする" do
51
+ expect {
52
+ invoke_ok = false
53
+ subject.connect_retry_count = 3
54
+ subject.connect_retry_inteval = 1
55
+ subject.connect do |conn|
56
+ raise Errno::ETIMEDOUT
57
+ invoke_ok = true
58
+ end
59
+ invoke_ok.should be_false
60
+ }.to raise_error
61
+ end
62
+ end
63
+
64
+ # [bug] 仮想マシン停止命令発行後starting状態が表示される
65
+ context "仮想マシン停止後の起動" do
66
+ before do
67
+ c = mock(::Tama::Controllers::ControllerFactory.allocate)
68
+ ::Tama::Controllers::ControllerFactory.
69
+ stub(:create_controller).
70
+ with("a-shpoolxx", "10.10.10.10", 8000, "http", "192.168.2.22", 9001, "https").
71
+ and_return(c)
72
+ c.stub(:terminate_instances).
73
+ with(["i-f222222d"]).
74
+ and_return([{
75
+ :aws_shutdown_state => nil,
76
+ :aws_instance_id => "i-f222222d",
77
+ :aws_shutdown_state_code => nil,
78
+ :aws_prev_state => nil,
79
+ :aws_prev_state_code => nil,
80
+ }])
81
+ c.stub(:run_instances).
82
+ with("wmi-lucid5", 1, 1, [], "ssh-xxxxx", "", nil, "is-small", nil, nil, "foo-dc", nil).
83
+ and_return([{
84
+ :aws_image_id => "wmi-lucid5",
85
+ :aws_reason => "",
86
+ :aws_state_code => "0",
87
+ :aws_owner => "000000000888",
88
+ :aws_instance_id => "i-abcdabcd",
89
+ :aws_reservation_id => "r-aabbccdd",
90
+ :aws_state => "pending",
91
+ :dns_name => "",
92
+ :ssh_key_name => "ssh-xxxxxx",
93
+ :aws_groups => [""],
94
+ :private_dns_name => "",
95
+ :aws_instance_type => "is-small",
96
+ :aws_launch_time => "2008-1-1T00:00:00.000Z",
97
+ :aws_ramdisk_id => "",
98
+ :aws_kernel_id => "",
99
+ :ami_launch_index => "0",
100
+ :aws_availability_zone => "",
101
+ }])
102
+ # キーを指定
103
+ subject.update_attributes(:properties => {
104
+ :key_name => "ssh-xxxxx"
105
+ })
106
+ Tengine::Resource::Server.delete_all
107
+ subject.virtual_servers.create(
108
+ :provided_id => 'i-f222222d',
109
+ :name => 'i-f222222d',
110
+ :status => 'running')
111
+ end
112
+
113
+ it "statusは変更しない" do
114
+ # 停止
115
+ va = subject.terminate_virtual_servers(subject.virtual_servers)
116
+ va.count.should == 1
117
+ v = va[0]
118
+ v.should_not be_nil
119
+ v.should be_valid
120
+ v.provided_id.should == 'i-f222222d'
121
+ v.status.should == 'running'
122
+
123
+ vi = subject.virtual_server_images.create(:provided_id => "wmi-lucid5")
124
+ vt = subject.virtual_server_types.create(:provided_id => "is-small")
125
+ ps = subject.physical_servers.create(:provided_id => "foo-dc")
126
+
127
+ # 起動
128
+ vs = subject.create_virtual_servers("i-abcdabcd", vi, vt, ps, "description", 1)
129
+ vs.count.should == 1
130
+ vserver = vs.first
131
+ vserver.should be_valid
132
+ vserver.provided_id.should == 'i-abcdabcd'
133
+ vserver.status.should == 'pending'
134
+ end
135
+ end
136
+
137
+ context "仮想マシンの起動" do
138
+ before do
139
+ c = mock(::Tama::Controllers::ControllerFactory.allocate)
140
+ ::Tama::Controllers::ControllerFactory.
141
+ stub(:create_controller).
142
+ with("a-shpoolxx", "10.10.10.10", 8000, "http", "192.168.2.22", 9001, "https").
143
+ and_return(c)
144
+ c.stub(:run_instances).
145
+ with("wmi-lucid5", 1, 1, [], "ssh-xxxxx", "", nil, "is-small", nil, nil, "foo-dc", nil).
146
+ and_return([{
147
+ :aws_image_id => "wmi-lucid5",
148
+ :aws_reason => "",
149
+ :aws_state_code => "0",
150
+ :aws_owner => "000000000888",
151
+ :aws_instance_id => "i-123f1234",
152
+ :aws_reservation_id => "r-aabbccdd",
153
+ :aws_state => "pending",
154
+ :dns_name => "",
155
+ :ssh_key_name => "ssh-xxxxxx",
156
+ :aws_groups => [""],
157
+ :private_dns_name => "",
158
+ :aws_instance_type => "is-small",
159
+ :aws_launch_time => "2008-1-1T00:00:00.000Z",
160
+ :aws_ramdisk_id => "",
161
+ :aws_kernel_id => "",
162
+ :ami_launch_index => "0",
163
+ :aws_availability_zone => "",
164
+ }])
165
+ c.stub(:run_instances).
166
+ with("wmi-lucid6", 1, 1, [], nil, "", nil, "is-micro", nil, nil, "foo-server", nil).
167
+ and_return([{
168
+ :aws_image_id => "wmi-lucid6",
169
+ :aws_reason => "",
170
+ :aws_state_code => "0",
171
+ :aws_owner => "000000000888",
172
+ :aws_instance_id => "i-123f1234",
173
+ :aws_reservation_id => "r-aabbccdd",
174
+ :aws_state => "pending",
175
+ :dns_name => "",
176
+ :aws_groups => [""],
177
+ :private_dns_name => "",
178
+ :aws_instance_type => "is-micro",
179
+ :aws_launch_time => "2008-1-1T00:00:00.000Z",
180
+ :aws_ramdisk_id => "",
181
+ :aws_kernel_id => "",
182
+ :ami_launch_index => "0",
183
+ :aws_availability_zone => "",
184
+ }])
185
+ end
186
+
187
+ it "1台の起動" do
188
+ # キーを指定
189
+ subject.update_attributes(:properties => {
190
+ :key_name => "ssh-xxxxx"
191
+ })
192
+ vi = subject.virtual_server_images.create(:provided_id => "wmi-lucid5")
193
+ vt = subject.virtual_server_types.create(:provided_id => "is-small")
194
+ ps = subject.physical_servers.create(:provided_id => "foo-dc")
195
+ vs = subject.create_virtual_servers("name", vi, vt, ps, "description", 1)
196
+ vs.count.should == 1
197
+ v = vs.first
198
+ v.should be_valid
199
+ v.name.should == "name001"
200
+ v.provided_type_id.should_not be_nil
201
+ v.provided_type_id.should_not be_empty
202
+ end
203
+
204
+ it "keyがない場合の起動" do
205
+ vi = subject.virtual_server_images.create(:provided_id => "wmi-lucid6")
206
+ vt = subject.virtual_server_types.create(:provided_id => "is-micro")
207
+ ps = subject.physical_servers.create(:provided_id => "foo-server")
208
+ vs = subject.create_virtual_servers("name", vi, vt, ps, "description", 1)
209
+ vs.count.should == 1
210
+ v = vs.first
211
+ v.name.should == "name001"
212
+ v.provided_type_id.should_not be_nil
213
+ v.provided_type_id.should_not be_empty
214
+ end
215
+ end
216
+
217
+ context "仮想マシンの停止" do
218
+ before do
219
+ Tengine::Resource::VirtualServer.delete_all
220
+ c = mock(::Tama::Controllers::ControllerFactory.allocate)
221
+ ::Tama::Controllers::ControllerFactory.
222
+ stub(:create_controller).
223
+ with("a-shpoolxx", "10.10.10.10", 8000, "http", "192.168.2.22", 9001, "https").
224
+ and_return(c)
225
+ c.stub(:terminate_instances).
226
+ with(["i-f222222d"]).
227
+ and_return([{
228
+ :aws_shutdown_state => nil,
229
+ :aws_instance_id => "i-f222222d",
230
+ :aws_shutdown_state_code => nil,
231
+ :aws_prev_state => nil,
232
+ :aws_prev_state_code => nil,
233
+ }])
234
+ c.stub(:terminate_instances).
235
+ with(["i-f222222d", "i-f222222e"]).
236
+ and_return([{
237
+ :aws_shutdown_state => nil,
238
+ :aws_instance_id => "i-f222222d",
239
+ :aws_shutdown_state_code => nil,
240
+ :aws_prev_state => nil,
241
+ :aws_prev_state_code => nil,
242
+ }, {
243
+ :aws_shutdown_state => nil,
244
+ :aws_instance_id => "i-f222222e",
245
+ :aws_shutdown_state_code => nil,
246
+ :aws_prev_state => nil,
247
+ :aws_prev_state_code => nil,
248
+ }])
249
+ end
250
+
251
+ it "1台の停止" do
252
+ vs = subject.virtual_servers.create(:provided_id => 'i-f222222d', :name => 'i-f222222d')
253
+ va = subject.terminate_virtual_servers([vs])
254
+ va.count.should == 1
255
+ v = va[0]
256
+ v.should_not be_nil
257
+ v.should be_valid
258
+ v.provided_id.should == 'i-f222222d'
259
+ end
260
+
261
+ it "複数台の停止" do
262
+ v1 = subject.virtual_servers.create(:provided_id => 'i-f222222d', :name => 'i-f222222d')
263
+ v2 = subject.virtual_servers.create(:provided_id => 'i-f222222e', :name => 'i-f222222e')
264
+ va = subject.terminate_virtual_servers([v1 ,v2])
265
+ va.count.should == 2
266
+ va[0].should_not be_nil
267
+ va[0].should be_valid
268
+ va[0].provided_id.should == 'i-f222222d'
269
+ va[1].should_not be_nil
270
+ va[1].should be_valid
271
+ va[1].provided_id.should == 'i-f222222e'
272
+ end
273
+ end
274
+
275
+ context "起動可能数の算出" do
276
+ before do
277
+ Tengine::Resource::Server.delete_all
278
+ t1 = subject.virtual_server_types.create(:provided_id => "t1", :caption => "t1", :cpu_cores => 1, :memory_size => 2 * 1024 * 1024 * 1024)
279
+ t2 = subject.virtual_server_types.create(:provided_id => "t2", :caption => "t2", :cpu_cores => 1, :memory_size => 4 * 1024 * 1024 * 1024)
280
+ t3 = subject.virtual_server_types.create(:provided_id => "t3", :caption => "t3", :cpu_cores => 2, :memory_size => 4 * 1024 * 1024 * 1024)
281
+ t4 = subject.virtual_server_types.create(:provided_id => "t4", :caption => "t4", :cpu_cores => 2, :memory_size => 8 * 1024 * 1024 * 1024)
282
+ t5 = subject.virtual_server_types.create(:provided_id => "t5", :caption => "t5", :cpu_cores => 4, :memory_size => 8 * 1024 * 1024 * 1024)
283
+ t6 = subject.virtual_server_types.create(:provided_id => "t6", :caption => "t6", :cpu_cores => 6, :memory_size => 8 * 1024 * 1024 * 1024)
284
+ physical1 = subject.physical_servers.create!(:name => "physical1", :provided_id => "server1", :status => :online, :cpu_cores => 8, :memory_size => 16 * 1024 * 1024 * 1024 )
285
+ physical2 = subject.physical_servers.create!(:name => "physical2", :provided_id => "server2", :status => :online, :cpu_cores => 12, :memory_size => 24 * 1024 * 1024 * 1024 )
286
+ physical3 = subject.physical_servers.create!(:name => "physical3", :provided_id => "server3", :status => :offline, :cpu_cores => 12, :memory_size => 24 * 1024 * 1024 * 1024 )
287
+ virtual11 = subject.virtual_servers.create!(:host_server => physical1, :name => "virtual11", :provided_id => "server11", :status => :running, :provided_type_id => "t6") # 6 * 8
288
+ virtual12 = subject.virtual_servers.create!(:host_server => physical1, :name => "virtual12", :provided_id => "server12", :status => :running, :provided_type_id => "t2") # 1 * 4
289
+ # physical1の空き cpu = 8 - (6 + 1) = 1, mem = 16 - (8 + 4) = 4
290
+
291
+ virtual21 = subject.virtual_servers.create!(:host_server => physical2, :name => "virtual21", :provided_id => "server21", :status => :running, :provided_type_id => "t3") # 2 * 4
292
+ virtual22 = subject.virtual_servers.create!(:host_server => physical2, :name => "virtual22", :provided_id => "server22", :status => :running, :provided_type_id => "t6") # 6 * 8
293
+ # physical2の空き cpu = 12 - (2 + 6) = 4, mem = 24 - (4 + 8) = 12
294
+ end
295
+
296
+ it do
297
+ subject.capacities.should == {
298
+ 'server1' => {
299
+ 't1' => 1,
300
+ 't2' => 1,
301
+ 't3' => 0,
302
+ 't4' => 0,
303
+ 't5' => 0,
304
+ 't6' => 0,
305
+ },
306
+ 'server2' => {
307
+ 't1' => 4,
308
+ 't2' => 3,
309
+ 't3' => 2,
310
+ 't4' => 1,
311
+ 't5' => 1,
312
+ 't6' => 0,
313
+ },
314
+ 'server3' => {
315
+ 't1' => 0,
316
+ 't2' => 0,
317
+ 't3' => 0,
318
+ 't4' => 0,
319
+ 't5' => 0,
320
+ 't6' => 0,
321
+ },
322
+ }
323
+ end
324
+
325
+ it "https://www.pivotaltracker.com/story/show/23338711" do
326
+ subject.virtual_servers.find_by_name("virtual11").update_attributes(:status => :terminated)
327
+ subject.capacities['server1'].should == {
328
+ 't1' => 6,
329
+ 't2' => 3,
330
+ 't3' => 3,
331
+ 't4' => 1,
332
+ 't5' => 1,
333
+ 't6' => 1,
334
+ }
335
+ end
336
+
337
+ end
338
+
339
+ end
@@ -0,0 +1,252 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe Tengine::Resource::Provider do
5
+
6
+ valid_attributes1 = {
7
+ :name => "provider1"
8
+ }.freeze
9
+
10
+ context "nameは必須" do
11
+ it "正常系" do
12
+ Tengine::Resource::Provider.delete_all
13
+ credential1 = Tengine::Resource::Provider.new(valid_attributes1)
14
+ credential1.valid?.should == true
15
+ end
16
+
17
+ [:name].each do |key|
18
+ it "#{key}なし" do
19
+ attrs = valid_attributes1.dup
20
+ attrs.delete(key)
21
+ credential1 = Tengine::Resource::Provider.new(attrs)
22
+ credential1.valid?.should == false
23
+ end
24
+ end
25
+
26
+ end
27
+
28
+ context "nameはユニーク" do
29
+ before do
30
+ Tengine::Resource::Provider.delete_all
31
+ @credential1 = Tengine::Resource::Provider.create!(valid_attributes1)
32
+ end
33
+
34
+ it "同じ名前で登録されているものが存在する場合エラー" do
35
+ expect{
36
+ @credential1 = Tengine::Resource::Provider.create!(valid_attributes1)
37
+ }.to raise_error(Mongoid::Errors::Validations, "Validation failed - Name is already taken.")
38
+ end
39
+ end
40
+
41
+ context "nameはベース名として定義される文字列です" do
42
+ it "スラッシュ'/’はリソース識別子で使われるのでnameには使用できません" do
43
+ server1 = Tengine::Resource::Provider.new(:name => "foo/bar")
44
+ server1.valid?.should == false
45
+ server1.errors[:name].should == [Tengine::Core::Validation::BASE_NAME.message]
46
+ end
47
+
48
+ it "コロン':'はリソース識別子で使われるのでnameには使用できません" do
49
+ server1 = Tengine::Resource::Provider.new(:name => "foo:bar")
50
+ server1.valid?.should == false
51
+ server1.errors[:name].should == [Tengine::Core::Validation::BASE_NAME.message]
52
+ end
53
+ end
54
+
55
+ context "nameで検索" do
56
+ before do
57
+ Tengine::Resource::Provider.delete_all
58
+ @fixture = GokuAtEc2ApNortheast.new
59
+ @provider1 = @fixture.provider
60
+ end
61
+
62
+ context "見つかる場合" do
63
+ it "find_by_name" do
64
+ found_credential = nil
65
+ lambda{
66
+ found_credential = Tengine::Resource::Provider.find_by_name(@provider1.name)
67
+ }.should_not raise_error
68
+ found_credential.should_not be_nil
69
+ found_credential.id.should == @provider1.id
70
+ end
71
+
72
+ it "find_by_name!" do
73
+ found_credential = nil
74
+ lambda{
75
+ found_credential = Tengine::Resource::Provider.find_by_name!(@provider1.name)
76
+ }.should_not raise_error
77
+ found_credential.should_not be_nil
78
+ found_credential.id.should == @provider1.id
79
+ end
80
+ end
81
+
82
+ context "見つからない場合" do
83
+ it "find_by_name" do
84
+ found_credential = Tengine::Resource::Provider.find_by_name("unexist_name").should == nil
85
+ end
86
+
87
+ it "find_by_name!" do
88
+ lambda{
89
+ found_credential = Tengine::Resource::Provider.find_by_name!("unexist_name")
90
+ }.should raise_error(Tengine::Core::FindByName::Error)
91
+ end
92
+ end
93
+
94
+ end
95
+
96
+
97
+ describe "<BUG>仮想サーバ起動画面から仮想サーバを起動すると仮想サーバが2重に登録され、仮想サーバ一覧でも2つ表示される" do
98
+ {
99
+ # 現在のtamaのテストモードでは、host_nodを指定していても指定しなくてもaws_availability_zoneを返さないので
100
+ # 以下の2つのテスト用ファイルによって返されるレスポンスは同じになってしまいますが、せっかく書いたので、将来のために残しておきます
101
+ '41_run_instances_1_virtual_servers.json' => "aws_availability_zoneが返ってくる場合",
102
+ '43_run_instances_1_virtual_servers_without_aws_availability_zone.json' => "aws_availability_zoneが空文字列"
103
+ }.each do |run_instance_file, msg|
104
+ context msg do
105
+
106
+ before do
107
+ Tengine::Resource::PhysicalServer.delete_all
108
+ Tengine::Resource::VirtualServer.delete_all
109
+ Tengine::Resource::Provider.delete_all
110
+ test_files_dir = File.expand_path("test_files", File.dirname(__FILE__))
111
+ @provider = Tengine::Resource::Provider::Wakame.create!(:name => "Wakame",
112
+ :connection_settings => {
113
+ :test => true,
114
+ :options => {
115
+ # :describe_instance_specs_file => File.expand_path('describe_instance_specs.json', test_files_dir) # 仮想サーバスペックの状態
116
+ # :describe_images_file => File.expand_path('describe_images.json', test_files_dir), # 仮想サーバイメージの状態
117
+ # :terminate_instances_file => File.expand_path('terminate_instances.json', test_files_dir), # 仮想サーバ停止時
118
+ # :describe_host_nodes_file => File.expand_path('describe_host_nodes.json', test_files_dir), # 物理サーバの状態
119
+ # 仮想サーバを一台だけ起動して、describe_instancesもその情報を返す
120
+ :run_instances_file => File.expand_path(run_instance_file, test_files_dir), # 仮想サーバ起動時
121
+ :describe_instances_file => File.expand_path('14_describe_instances_after_run_1_instance.json', test_files_dir), # 仮想サーバの状態
122
+ }
123
+ })
124
+ @physical_server01 = @provider.physical_servers.create!(
125
+ :name => "physical_server_uuid_01",
126
+ :provided_id => "physical_server_uuid_01",
127
+ :status => "online", :cpu_core => 16, :memory_size => 1000)
128
+ end
129
+
130
+ it "プロバイダへのリクエスト送信直後、登録処理を行う前に、tengine_resource_watchdが登録を行ってしまうと、二重登録される" do
131
+ expect{
132
+ expect{
133
+ results = @provider.create_virtual_servers(
134
+ "test",
135
+ mock(:server_image1, :provided_id => "img-aaaa"),
136
+ mock(:server_type1, :provided_id => "type1"),
137
+ @physical_server01,
138
+ "", 1) do
139
+ # このブロックはテスト用に使われるもので、リクエストを送った直後、データを登録する前に呼び出されます。
140
+ @provider.virtual_server_watch # 先にtengine_resource_watchdが更新してしまう
141
+ end
142
+ results.each{|result| result.should_not == nil}
143
+ }.to_not raise_error
144
+ }.to change(Tengine::Resource::VirtualServer, :count).by(1) # 1台だけ起動される
145
+ server1 = Tengine::Resource::VirtualServer.first(:conditions => {:provided_id => "virtual_server_uuid_91"})
146
+ server1.host_server_id.should == @physical_server01.id
147
+ end
148
+
149
+ context "重複チェックを行った後に、別のプロセスなどとほとんど同時に書き込んだ場合は、バリデーションエラー/一意制約違反となるがエラーとしては扱わない" do
150
+ [:ja, :en, nil].each do |locale|
151
+ it "localeが#{locale.inspect}" do
152
+ I18n.locale = locale
153
+ expect{
154
+ expect{
155
+ @provider.virtual_servers.should_receive(:find).with(any_args).and_return do
156
+ @provider.virtual_server_watch # 先にtengine_resource_watchdが更新してしまう
157
+ 0 # 「重複するものは見つからなかった」
158
+ end
159
+ results = @provider.create_virtual_servers(
160
+ "test",
161
+ mock(:server_image1, :provided_id => "img-aaaa"),
162
+ mock(:server_type1, :provided_id => "type1"),
163
+ @physical_server01,
164
+ "", 1
165
+ )
166
+ results.each{|result| result.should_not == nil}
167
+ }.to_not raise_error
168
+ }.to change(Tengine::Resource::VirtualServer, :count).by(1) # 1台だけ起動される
169
+ server1 = Tengine::Resource::VirtualServer.first(:conditions => {:provided_id => "virtual_server_uuid_91"})
170
+ server1.host_server_id.should == @physical_server01.id
171
+ end
172
+ end
173
+ end
174
+
175
+ context "登録を行った直後に、別のプロセスなどとほとんど同時に書き込んだ場合は、バリデーションエラー/一意制約違反となるがエラーとしては扱わない" do
176
+
177
+ instance_hash = {
178
+ :aws_kernel_id=>"",
179
+ :aws_launch_time=>"2011-10-18T06:51:16Z",
180
+ :tags=>{},
181
+ :aws_reservation_id=>"",
182
+ :aws_owner=>"a-shpoolxx",
183
+ :instance_lifecycle=>"",
184
+ :block_device_mappings=>
185
+ [{:ebs_volume_id=>"",
186
+ :ebs_status=>"",
187
+ :ebs_attach_time=>"",
188
+ :ebs_delete_on_termination=>false,
189
+ :device_name=>""}],
190
+ :ami_launch_index=>"",
191
+ :root_device_name=>"",
192
+ :aws_ramdisk_id=>"",
193
+ :aws_availability_zone=>"physical_server_uuid_01",
194
+ :aws_groups=>nil,
195
+ :spot_instance_request_id=>"",
196
+ :ssh_key_name=>nil,
197
+ :virtualization_type=>"",
198
+ :placement_group_name=>"",
199
+ :requester_id=>"",
200
+ :aws_instance_id=>"virtual_server_uuid_91",
201
+ :aws_product_codes=>[],
202
+ :client_token=>"",
203
+ :private_ip_address=>"192.168.2.91",
204
+ :architecture=>"x86_64",
205
+ :aws_state_code=>0,
206
+ :aws_image_id=>"virtual_server_image_uuid_01",
207
+ :root_device_type=>"",
208
+ :ip_address=>
209
+ "nw-data=192.168.2.91,nw-outside=172.16.0.91,nw-data_2=192.168.3.91,nw-outside_2=172.16.1.91",
210
+ :dns_name=>
211
+ "nw-data=jria301q.shpoolxx.vdc.local,nw-outside=jria301q.shpoolxx.vdc.public,nw-data_2=jria301q.shpoolxx.vdc.local,nw-outside_2=jria301q.shpoolxx.vdc.public",
212
+ :monitoring_state=>"",
213
+ :aws_instance_type=>"virtual_server_spec_uuid_01",
214
+ :aws_state=>"running",
215
+ :private_dns_name=>"jria301q.shpoolxx.vdc.local",
216
+ :aws_reason=>""
217
+ }
218
+
219
+ [:ja, :en, nil].each do |locale|
220
+ it "localeが#{locale.inspect}" do
221
+ I18n.locale = locale
222
+ @provider.stub(:partion_instances).and_return([
223
+ [instance_hash], [], []
224
+ ])
225
+ @physical_server01.provided_id.should == "physical_server_uuid_01"
226
+ expect{
227
+ # expect{
228
+ results = @provider.create_virtual_servers(
229
+ "test",
230
+ mock(:server_image1, :provided_id => "img-aaaa"),
231
+ mock(:server_type1, :provided_id => "type1"),
232
+ @physical_server01,
233
+ "", 1)
234
+ results.each{|result| result.should_not == nil}
235
+ server1 = Tengine::Resource::VirtualServer.first(:conditions => {:provided_id => "virtual_server_uuid_91"})
236
+ server1.host_server.should_not == nil
237
+ server1.host_server_id.should == @physical_server01.id
238
+
239
+ @provider.virtual_server_watch # 後からtengine_resource_watchdが更新しようとする
240
+ # }.to_not raise_error
241
+ }.to change(Tengine::Resource::VirtualServer, :count).by(1) # 1台だけ起動される
242
+ server1 = Tengine::Resource::VirtualServer.first(:conditions => {:provided_id => "virtual_server_uuid_91"})
243
+ server1.host_server_id.should == @physical_server01.id
244
+ end
245
+ end
246
+ end
247
+ end
248
+
249
+ end
250
+ end
251
+
252
+ end