engineyard 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
data/spec/ey/logs_spec.rb CHANGED
@@ -11,3 +11,21 @@ describe "ey logs" do
11
11
  @err.should be_empty
12
12
  end
13
13
  end
14
+
15
+ describe "ey logs ENV" do
16
+ it_should_behave_like "an integration test"
17
+
18
+ before(:all) do
19
+ api_scenario "one app, many similarly-named environments"
20
+ end
21
+
22
+ it "works when given an unambiguous substring" do
23
+ ey "logs prod"
24
+ @out.should match(/MAIN LOG OUTPUT/)
25
+ end
26
+
27
+ it "complains when given an ambiguous substring" do
28
+ ey "logs staging", :hide_err => true, :expect_failure => true
29
+ @err.should match(/'staging' is ambiguous/)
30
+ end
31
+ end
@@ -3,23 +3,40 @@ require 'spec_helper'
3
3
  describe "ey rebuild" do
4
4
  it_should_behave_like "an integration test"
5
5
 
6
- before(:each) do
6
+ before(:all) do
7
7
  api_scenario "one app, one environment"
8
8
  end
9
9
 
10
10
  it "works when the environment name is valid" do
11
- ey "rebuild giblets"
11
+ ey "rebuild giblets", :debug => true
12
12
  @out.should =~ /Rebuilding giblets/i
13
13
  end
14
14
 
15
15
  it "rebuilds the current environment by default" do
16
- ey "rebuild"
16
+ ey "rebuild", :debug => true
17
17
  @out.should =~ /Rebuilding giblets/i
18
18
  end
19
19
 
20
20
  it "fails when the environment name is bogus" do
21
- ey "rebuild typo", :hide_err => true, :expect_failure => true
21
+ ey "rebuild typo", :expect_failure => true
22
22
  @err.should match(/No environment named 'typo'/)
23
23
  end
24
24
  end
25
25
 
26
+ describe "ey rebuild ENV" do
27
+ it_should_behave_like "an integration test"
28
+
29
+ before(:all) do
30
+ api_scenario "one app, many similarly-named environments"
31
+ end
32
+
33
+ it "works when given an unambiguous substring" do
34
+ ey "rebuild prod", :debug => true
35
+ @out.should =~ /Rebuilding railsapp_production/
36
+ end
37
+
38
+ it "complains when given an ambiguous substring" do
39
+ ey "rebuild staging", :hide_err => true, :expect_failure => true
40
+ @err.should =~ /'staging' is ambiguous/
41
+ end
42
+ end
data/spec/ey/ssh_spec.rb CHANGED
@@ -4,21 +4,46 @@ describe "ey ssh" do
4
4
  it_should_behave_like "an integration test"
5
5
 
6
6
  before(:all) do
7
- api_scenario "one app, one environment"
7
+ api_scenario "one app, two environments"
8
8
  end
9
9
 
10
10
  it "SSH-es into the right environment" do
11
11
  print_my_args = "#!/bin/sh\necho ssh $*"
12
12
 
13
13
  ey "ssh giblets", :prepend_to_path => {'ssh' => print_my_args}
14
- @ssh_commands.should == ["ssh turkey@174.129.198.124"]
14
+ @raw_ssh_commands.should == ["ssh turkey@174.129.198.124"]
15
+ end
16
+
17
+ it "complains if it has no app master" do
18
+ ey "ssh bakon", :expect_failure => true
19
+ @err.should =~ /'bakon' does not have a master instance/
15
20
  end
16
21
 
17
22
  it "complains if you give it a bogus environment" do
18
23
  print_my_args = "#!/bin/sh\necho ssh $*"
19
24
 
20
25
  ey "ssh bogusenv", :prepend_to_path => {'ssh' => print_my_args}, :hide_err => true
21
- @ssh_commands.should be_empty
26
+ @raw_ssh_commands.should be_empty
22
27
  @out.should =~ /could not find.*bogusenv/i
23
28
  end
24
29
  end
30
+
31
+ describe "ey ssh ENV" do
32
+ it_should_behave_like "an integration test"
33
+
34
+ before(:all) do
35
+ api_scenario "one app, many similarly-named environments"
36
+ end
37
+
38
+ it "works when given an unambiguous substring" do
39
+ print_my_args = "#!/bin/sh\necho ssh $*"
40
+
41
+ ey "ssh prod", :prepend_to_path => {'ssh' => print_my_args}
42
+ @raw_ssh_commands.should == ["ssh turkey@174.129.198.124"]
43
+ end
44
+
45
+ it "complains when given an ambiguous substring" do
46
+ ey "ssh staging", :hide_err => true, :expect_failure => true
47
+ @err.should match(/'staging' is ambiguous/)
48
+ end
49
+ end
data/spec/spec_helper.rb CHANGED
@@ -14,6 +14,7 @@ end
14
14
  require 'fakeweb'
15
15
  require 'fakeweb_matcher'
16
16
  require 'fakefs/safe'
17
+ require 'json'
17
18
 
18
19
  # Engineyard gem
19
20
  $LOAD_PATH.unshift(File.join(EY_ROOT, "lib"))
@@ -22,11 +23,10 @@ require 'engineyard'
22
23
  # Spec stuff
23
24
  require 'spec/autorun'
24
25
  require 'yaml'
26
+ require 'pp'
25
27
  support = Dir[File.join(EY_ROOT,'/spec/support/*.rb')]
26
28
  support.each{|helper| require helper }
27
29
 
28
- EY.start_fake_awsm
29
-
30
30
  Spec::Runner.configure do |config|
31
31
  config.include Spec::Helpers
32
32
 
@@ -43,29 +43,54 @@ Spec::Runner.configure do |config|
43
43
  end
44
44
  end
45
45
 
46
- # Use this in conjunction with the 'ey' helper method
47
- shared_examples_for "an integration test" do
46
+ Spec::Matchers.define :have_command_like do |regex|
47
+ match do |command_list|
48
+ @found = command_list.find{|c| c =~ regex }
49
+ !!@found
50
+ end
51
+
52
+ failure_message_for_should do |command_list|
53
+ "Didn't find a command matching #{regex} in commands:\n\n" + command_list.join("\n\n")
54
+ end
55
+
56
+ failure_message_for_should_not do |command_list|
57
+ "Found unwanted command:\n\n#{@found}\n\n(matches regex #{regex})"
58
+ end
59
+ end
60
+
61
+ shared_examples_for "an integration test without an eyrc file" do
48
62
  before(:all) do
49
63
  FakeFS.deactivate!
50
64
  ENV['EYRC'] = "/tmp/eyrc"
51
- ENV['CLOUD_URL'] = EY.fake_awsm
52
65
  FakeWeb.allow_net_connect = true
66
+ ENV['CLOUD_URL'] = EY.fake_awsm
67
+ end
53
68
 
54
- token = { ENV['CLOUD_URL'] => {
55
- "api_token" => "f81a1706ddaeb148cfb6235ddecfc1cf"} }
56
- File.open(ENV['EYRC'], "w"){|f| YAML.dump(token, f) }
69
+ before(:each) do
70
+ api_git_remote nil
57
71
  end
58
72
 
59
73
  after(:all) do
60
- ENV['CLOUD_URL'] = nil
74
+ ENV.delete('CLOUD_URL')
75
+ ENV.delete('EYRC')
61
76
  FakeFS.activate!
62
77
  FakeWeb.allow_net_connect = false
63
78
  end
64
79
  end
65
80
 
66
- shared_examples_for "it has an account" do
81
+ # Use this in conjunction with the 'ey' helper method
82
+ shared_examples_for "an integration test" do
83
+ it_should_behave_like "an integration test without an eyrc file"
84
+
85
+ before(:all) do
86
+ token = { ENV['CLOUD_URL'] => {
87
+ "api_token" => "f81a1706ddaeb148cfb6235ddecfc1cf"} }
88
+ File.open(ENV['EYRC'], "w"){|f| YAML.dump(token, f) }
89
+ end
90
+ end
91
+
92
+ shared_examples_for "it has an api" do
67
93
  before(:all) do
68
- write_yaml({"api_token" => "asdf"}, "~/.eyrc")
69
- @account = EY::Account.new(EY::API.new)
94
+ @api = EY::API.new('asdf')
70
95
  end
71
96
  end
@@ -30,6 +30,8 @@ class FakeAwsm < Sinatra::Base
30
30
  Scenario::LinkedApp
31
31
  when "one app, two environments"
32
32
  Scenario::OneAppTwoEnvs
33
+ when "one app, many similarly-named environments"
34
+ Scenario::OneAppManySimilarlyNamedEnvs
33
35
  end
34
36
  if new_scenario
35
37
  @@scenario = new_scenario
@@ -119,7 +121,7 @@ private
119
121
  def self.environments
120
122
  []
121
123
  end
122
- end
124
+ end # Empty
123
125
 
124
126
  class UnlinkedApp
125
127
  extend FindableGitRemote
@@ -148,7 +150,7 @@ private
148
150
  "status" => "running",
149
151
  "id" => 27220}}]
150
152
  end
151
- end
153
+ end # UnlinkedApp
152
154
 
153
155
  class LinkedApp
154
156
  extend FindableGitRemote
@@ -199,7 +201,7 @@ private
199
201
  "custom" => "CUSTOM LOG OUTPUT"
200
202
  }]
201
203
  end
202
- end
204
+ end # LinkedApp
203
205
 
204
206
  class OneAppTwoEnvs
205
207
  extend FindableGitRemote
@@ -268,7 +270,140 @@ private
268
270
  "app_master" => nil,
269
271
  }]
270
272
  end
271
- end
273
+ end # OneAppTwoEnvs
274
+
275
+ class OneAppManySimilarlyNamedEnvs
276
+ extend FindableGitRemote
277
+
278
+ def self.apps
279
+ apps = [{
280
+ "name" => "rails232app",
281
+ "repository_uri" => git_remote
282
+ }]
283
+
284
+ [{"name" => "rails232app",
285
+ "environments" => [{
286
+ "ssh_username" => "turkey",
287
+ "instances" => [{
288
+ "public_hostname" => "174.129.198.124",
289
+ "status" => "running",
290
+ "id" => 27220}],
291
+ "name" => "railsapp_production",
292
+ "apps" => apps,
293
+ "instances_count" => 1,
294
+ "stack_name" => "nginx_mongrel",
295
+ "id" => 200,
296
+ "app_master" => {
297
+ "public_hostname" => "174.129.198.124",
298
+ "status" => "running",
299
+ "id" => 27220,
300
+ },
301
+ }, {
302
+ "ssh_username" => "ham",
303
+ "instances" => [{
304
+ "public_hostname" => '127.3.2.1',
305
+ "status" => "running",
306
+ "id" => 63066,
307
+ }],
308
+ "name" => "railsapp_staging",
309
+ "apps" => apps,
310
+ "instances_count" => 1,
311
+ "stack_name" => "nginx_passenger",
312
+ "id" => 8371,
313
+ "app_master" => {
314
+ "public_hostname" => '127.3.2.1',
315
+ "status" => "running",
316
+ "id" => 63066,
317
+ },
318
+ }, {
319
+ "ssh_username" => "ham",
320
+ "instances" => [{
321
+ "public_hostname" => '127.44.55.66',
322
+ "status" => "running",
323
+ "id" => 59395,
324
+ }],
325
+ "name" => "railsapp_staging_2",
326
+ "apps" => apps,
327
+ "instances_count" => 1,
328
+ "stack_name" => "nginx_passenger",
329
+ "id" => 8371,
330
+ "app_master" => {
331
+ "public_hostname" => '127.44.55.66',
332
+ "status" => "running",
333
+ "id" => 59395,
334
+ },
335
+ }],
336
+ "repository_uri" => git_remote}]
337
+ end
338
+
339
+ def self.environments
340
+ [{
341
+ "ssh_username" => "turkey",
342
+ "instances" => [{
343
+ "public_hostname" => "174.129.198.124",
344
+ "status" => "running",
345
+ "id" => 27220}],
346
+ "name" => "railsapp_production",
347
+ "apps" => [{
348
+ "name" => "rails232app",
349
+ "repository_uri" => git_remote}],
350
+ "instances_count" => 1,
351
+ "stack_name" => "nginx_mongrel",
352
+ "id" => 200,
353
+ "app_master" => {
354
+ "public_hostname" => "174.129.198.124",
355
+ "status" => "running",
356
+ "id" => 27220}
357
+ }, {
358
+ "ssh_username" => "ham",
359
+ "instances" => [{
360
+ "public_hostname" => '127.3.2.1',
361
+ "status" => "running",
362
+ "id" => 63066,
363
+ }],
364
+ "name" => "railsapp_staging",
365
+ "apps" => [{
366
+ "name" => "rails232app",
367
+ "repository_uri" => git_remote}],
368
+ "instances_count" => 1,
369
+ "stack_name" => "nginx_passenger",
370
+ "id" => 8371,
371
+ "app_master" => {
372
+ "public_hostname" => '127.3.2.1',
373
+ "status" => "running",
374
+ "id" => 63066,
375
+ },
376
+ }, {
377
+ "ssh_username" => "chicken",
378
+ "instances" => [{
379
+ "public_hostname" => '127.44.55.66',
380
+ "status" => "running",
381
+ "id" => 59395,
382
+ }],
383
+ "name" => "railsapp_staging_2",
384
+ "apps" => [{
385
+ "name" => "rails232app",
386
+ "repository_uri" => git_remote}],
387
+ "instances_count" => 1,
388
+ "stack_name" => "nginx_passenger",
389
+ "id" => 8371,
390
+ "app_master" => {
391
+ "public_hostname" => '127.44.55.66',
392
+ "status" => "running",
393
+ "id" => 59395,
394
+ },
395
+ }]
396
+ end
397
+
398
+ def self.logs(env_id)
399
+ [{
400
+ "id" => env_id,
401
+ "role" => "app_master",
402
+ "main" => "MAIN LOG OUTPUT",
403
+ "custom" => "CUSTOM LOG OUTPUT"
404
+ }]
405
+ end
406
+ end # OneAppManySimilarlyNamedEnvs
272
407
  end
273
408
  end
274
409
 
@@ -18,12 +18,11 @@ module Spec
18
18
 
19
19
  def ey(cmd = nil, options = {}, &block)
20
20
  require "open3"
21
- hide_err = options.delete(:hide_err)
22
- path_prepends = options.delete(:prepend_to_path)
21
+ hide_err = options.has_key?(:hide_err) ? options[:hide_err] : options[:expect_failure]
22
+ path_prepends = options[:prepend_to_path]
23
23
 
24
- ey_env = {
25
- 'DEBUG' => options[:debug].to_s
26
- }
24
+ ey_env = {}
25
+ ey_env['DEBUG'] = options[:debug].to_s if options[:debug]
27
26
 
28
27
  if path_prepends
29
28
  tempdir = File.join(Dir.tmpdir, "ey_test_cmds_#{Time.now.tv_sec}#{Time.now.tv_usec}_#{$$}")
@@ -54,10 +53,22 @@ module Spec
54
53
  end
55
54
  end
56
55
 
57
- @ssh_commands = @out.split(/\n/).find_all do |line|
56
+ @raw_ssh_commands = @out.split(/\n/).find_all do |line|
58
57
  line =~ /^ssh/
59
- end.map do |line|
60
- line.sub(/^.*?\"/, '').sub(/\"$/, '')
58
+ end
59
+
60
+ @ssh_commands = @raw_ssh_commands.map do |cmd|
61
+ # Strip off everything up to and including user@host, leaving
62
+ # just the command that the remote system would run
63
+ ssh_prefix_removed = cmd.gsub(/^.*?\w+@\S*\s*/, '')
64
+
65
+ # Its arguments have been double-escaped: one layer is to get
66
+ # them through our local shell and into ssh, and the other
67
+ # layer is to get them through the remote system's shell.
68
+ #
69
+ # Strip off one layer by running it through the shell.
70
+ just_the_remote_command = ssh_prefix_removed.gsub(/>\s*\/dev\/null.*$/, '')
71
+ `echo #{just_the_remote_command}`.strip
61
72
  end
62
73
 
63
74
  puts @err unless @err.empty? || hide_err
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 3
8
- - 1
9
- version: 0.3.1
8
+ - 2
9
+ version: 0.3.2
10
10
  platform: ruby
11
11
  authors:
12
12
  - EY Cloud Team
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-05-18 00:00:00 -07:00
17
+ date: 2010-05-26 00:00:00 -07:00
18
18
  default_executable: ey
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -59,16 +59,16 @@ dependencies:
59
59
  version_requirements: *id003
60
60
  - !ruby/object:Gem::Dependency
61
61
  prerelease: false
62
- name: json
62
+ name: escape
63
63
  requirement: &id004 !ruby/object:Gem::Requirement
64
64
  requirements:
65
65
  - - ~>
66
66
  - !ruby/object:Gem::Version
67
67
  segments:
68
- - 1
69
- - 4
70
68
  - 0
71
- version: 1.4.0
69
+ - 0
70
+ - 4
71
+ version: 0.0.4
72
72
  type: :runtime
73
73
  version_requirements: *id004
74
74
  - !ruby/object:Gem::Dependency
@@ -84,6 +84,20 @@ dependencies:
84
84
  version: "1.4"
85
85
  type: :runtime
86
86
  version_requirements: *id005
87
+ - !ruby/object:Gem::Dependency
88
+ prerelease: false
89
+ name: json
90
+ requirement: &id006 !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ~>
93
+ - !ruby/object:Gem::Version
94
+ segments:
95
+ - 1
96
+ - 4
97
+ - 0
98
+ version: 1.4.0
99
+ type: :runtime
100
+ version_requirements: *id006
87
101
  description: This gem allows you to deploy your rails application to the Engine Yard cloud directly from the command line.
88
102
  email: cloud@engineyard.com
89
103
  executables:
@@ -94,23 +108,20 @@ extra_rdoc_files: []
94
108
 
95
109
  files:
96
110
  - bin/ey
97
- - lib/engineyard/account/api_struct.rb
98
- - lib/engineyard/account/app.rb
99
- - lib/engineyard/account/app_master.rb
100
- - lib/engineyard/account/environment.rb
101
- - lib/engineyard/account/instance.rb
102
- - lib/engineyard/account/log.rb
103
- - lib/engineyard/account.rb
104
- - lib/engineyard/action/deploy.rb
105
- - lib/engineyard/action/rebuild.rb
106
- - lib/engineyard/action/util.rb
107
111
  - lib/engineyard/api.rb
112
+ - lib/engineyard/cli/action/deploy.rb
108
113
  - lib/engineyard/cli/api.rb
109
114
  - lib/engineyard/cli/thor_fixes.rb
110
115
  - lib/engineyard/cli/ui.rb
111
116
  - lib/engineyard/cli.rb
112
117
  - lib/engineyard/config.rb
113
118
  - lib/engineyard/error.rb
119
+ - lib/engineyard/model/api_struct.rb
120
+ - lib/engineyard/model/app.rb
121
+ - lib/engineyard/model/environment.rb
122
+ - lib/engineyard/model/instance.rb
123
+ - lib/engineyard/model/log.rb
124
+ - lib/engineyard/model.rb
114
125
  - lib/engineyard/repo.rb
115
126
  - lib/engineyard/ruby_ext.rb
116
127
  - lib/engineyard.rb
@@ -147,13 +158,13 @@ signing_key:
147
158
  specification_version: 3
148
159
  summary: Command-line deployment for the Engine Yard cloud
149
160
  test_files:
150
- - spec/engineyard/account/api_struct_spec.rb
151
- - spec/engineyard/account/environment_spec.rb
152
- - spec/engineyard/account_spec.rb
153
161
  - spec/engineyard/api_spec.rb
154
162
  - spec/engineyard/cli/api_spec.rb
155
163
  - spec/engineyard/cli_spec.rb
156
164
  - spec/engineyard/config_spec.rb
165
+ - spec/engineyard/model/api_struct_spec.rb
166
+ - spec/engineyard/model/environment_spec.rb
167
+ - spec/engineyard/model/instance_spec.rb
157
168
  - spec/engineyard/repo_spec.rb
158
169
  - spec/engineyard_spec.rb
159
170
  - spec/ey/deploy_spec.rb