engineyard 1.3.1 → 1.3.2

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.
@@ -5,8 +5,9 @@ describe "ey web disable" do
5
5
 
6
6
  def command_to_run(opts)
7
7
  cmd = "web disable"
8
- cmd << " -e #{opts[:env]}" if opts[:env]
8
+ cmd << " -e #{opts[:environment]}" if opts[:environment]
9
9
  cmd << " -a #{opts[:app]}" if opts[:app]
10
+ cmd << " -c #{opts[:account]}" if opts[:account]
10
11
  cmd << " --verbose" if opts[:verbose]
11
12
  cmd
12
13
  end
@@ -15,7 +16,6 @@ describe "ey web disable" do
15
16
  @ssh_commands.should have_command_like(/engineyard-serverside.*deploy enable_maintenance_page.*--app #{scenario[:application]}/)
16
17
  end
17
18
 
18
- it_should_behave_like "it takes an environment name"
19
- it_should_behave_like "it takes an app name"
19
+ it_should_behave_like "it takes an environment name and an app name and an account name"
20
20
  it_should_behave_like "it invokes engineyard-serverside"
21
21
  end
@@ -5,8 +5,9 @@ describe "ey web enable" do
5
5
 
6
6
  def command_to_run(opts)
7
7
  cmd = "web enable"
8
- cmd << " -e #{opts[:env]}" if opts[:env]
8
+ cmd << " -e #{opts[:environment]}" if opts[:environment]
9
9
  cmd << " -a #{opts[:app]}" if opts[:app]
10
+ cmd << " -c #{opts[:account]}" if opts[:account]
10
11
  cmd << " --verbose" if opts[:verbose]
11
12
  cmd
12
13
  end
@@ -15,7 +16,6 @@ describe "ey web enable" do
15
16
  @ssh_commands.should have_command_like(/engineyard-serverside.*deploy disable_maintenance_page.*--app #{scenario[:application]}/)
16
17
  end
17
18
 
18
- it_should_behave_like "it takes an environment name"
19
- it_should_behave_like "it takes an app name"
19
+ it_should_behave_like "it takes an environment name and an app name and an account name"
20
20
  it_should_behave_like "it invokes engineyard-serverside"
21
21
  end
data/spec/spec_helper.rb CHANGED
@@ -29,6 +29,9 @@ require 'json'
29
29
  $LOAD_PATH.unshift(File.join(EY_ROOT, "lib"))
30
30
  require 'engineyard'
31
31
 
32
+ #autoload hax
33
+ EY::Error
34
+
32
35
  # Spec stuff
33
36
  require 'spec/autorun'
34
37
  require 'tmpdir'
@@ -39,7 +42,7 @@ support.each{|helper| require helper }
39
42
 
40
43
  Spec::Runner.configure do |config|
41
44
  config.include Spec::Helpers
42
- config.extend Spec::GitRepo
45
+ config.include Spec::GitRepo
43
46
  config.extend Spec::Helpers::SemanticNames
44
47
 
45
48
  config.before(:all) do
@@ -30,6 +30,8 @@ class FakeAwsm < Sinatra::Base
30
30
  Scenario::TwoApps
31
31
  when "one app, one environment"
32
32
  Scenario::LinkedApp
33
+ when "two accounts, two apps, two environments, ambiguous"
34
+ Scenario::MultipleAmbiguousAccounts
33
35
  when "one app, one environment, no instances"
34
36
  Scenario::LinkedAppNotRunning
35
37
  when "one app, one environment, app master red"
@@ -122,22 +124,31 @@ private
122
124
 
123
125
  class CloudMock
124
126
  def initialize(initial_conditions)
125
- @apps, @envs, @keys, @app_joins, @key_joins = [], [], [], [], []
127
+ @accounts, @apps, @envs, @keys, @app_joins, @key_joins = [], [], [], [], [], []
126
128
  @next_id = 1
127
129
 
130
+ initial_conditions.starting_accounts.each {|a| add_account(a) }
128
131
  initial_conditions.starting_apps.each {|a| add_app(a) }
129
132
  initial_conditions.starting_environments.each {|e| add_environment(e) }
130
133
  initial_conditions.starting_app_joins.each {|(app_id, env_id)| link_app(app_id, env_id) }
131
134
  end
132
135
 
136
+ def add_account(acc)
137
+ acc["id"] ||= next_id
138
+ @accounts << acc
139
+ acc
140
+ end
141
+
133
142
  def add_app(app)
134
143
  app["id"] ||= next_id
144
+ app["account"] ||= @accounts.first
135
145
  @apps << app
136
146
  app
137
147
  end
138
148
 
139
149
  def add_environment(env)
140
150
  env["id"] ||= next_id
151
+ env["account"] ||= @accounts.first
141
152
 
142
153
  unless env.has_key?("app_master")
143
154
  master = env["instances"].find{ |i| %w[solo app_master].include?(i["role"]) }
@@ -149,8 +160,11 @@ private
149
160
  end
150
161
 
151
162
  def link_app(app_id, env_id)
152
- @apps.find {|a| a["id"] == app_id } or raise "No such app id:#{app_id}"
153
- @envs.find {|e| e["id"] == env_id } or raise "No such environment id:#{env_id}"
163
+ app = @apps.find {|a| a["id"] == app_id } or raise "No such app id:#{app_id}"
164
+ env = @envs.find {|e| e["id"] == env_id } or raise "No such environment id:#{env_id}"
165
+ if app["account"]["id"] != env["account"]["id"]
166
+ raise "App #{app_id} in account #{app["account"]["id"]} cannot be attached to environment #{env_id} in account #{env["account"]["id"]}"
167
+ end
154
168
  @app_joins << [app_id, env_id]
155
169
  @app_joins.uniq!
156
170
  end
@@ -213,6 +227,7 @@ private
213
227
  self.git_remote = git_remote
214
228
  end
215
229
 
230
+ def starting_accounts() [{"name" => "main"}] end
216
231
  def starting_apps() [] end
217
232
  def starting_environments() [] end
218
233
  def starting_app_joins() [] end
@@ -298,6 +313,35 @@ private
298
313
 
299
314
  end # LinkedApp
300
315
 
316
+ class MultipleAmbiguousAccounts < LinkedApp
317
+ def starting_accounts
318
+ super + [{"name" => "account_2", "id" => 256}]
319
+ end
320
+
321
+ def starting_apps
322
+ apps = super
323
+ new_app = apps.first.dup
324
+ new_app["id"] += 1000
325
+ new_app["account"] = starting_accounts.last
326
+ apps + [new_app]
327
+ end
328
+
329
+ def starting_environments
330
+ envs = super
331
+ new_env = envs.first.dup
332
+ new_env["id"] += 1000
333
+ new_env["account"] = starting_accounts.last
334
+ envs + [new_env]
335
+ end
336
+
337
+ def starting_app_joins
338
+ joins = super
339
+ new_join = [joins.first[0] + 1000,
340
+ joins.first[1] + 1000]
341
+ joins + [new_join]
342
+ end
343
+ end
344
+
301
345
  class UnlinkedApp < Base
302
346
  def starting_apps
303
347
  [{
@@ -1,23 +1,36 @@
1
1
  module Spec
2
2
  module GitRepo
3
- def define_git_repo(name, &setup)
4
- # EY's ivars don't get cleared between examples, so we can keep
5
- # a git repo around longer (and thus make our tests faster)
6
- FakeFS.without { EY.define_git_repo(name, &setup) }
7
- end
3
+ module ClassMethods
8
4
 
9
- def use_git_repo(repo_name)
10
- before(:all) do
11
- FakeFS.without do
12
- @_original_wd ||= []
13
- @_original_wd << Dir.getwd
14
- Dir.chdir(EY.git_repo_dir(repo_name))
15
- end
5
+ def define_git_repo(name, &setup)
6
+ # EY's ivars don't get cleared between examples, so we can keep
7
+ # a git repo around longer (and thus make our tests faster)
8
+ FakeFS.without { EY.define_git_repo(name, &setup) }
16
9
  end
17
10
 
18
- after(:all) do
19
- FakeFS.without { Dir.chdir(@_original_wd.pop) }
11
+ def use_git_repo(repo_name)
12
+ before(:all) do
13
+ FakeFS.without do
14
+ @_original_wd ||= []
15
+ @_original_wd << Dir.getwd
16
+ Dir.chdir(EY.git_repo_dir(repo_name))
17
+ end
18
+ end
19
+
20
+ after(:all) do
21
+ FakeFS.without { Dir.chdir(@_original_wd.pop) }
22
+ end
20
23
  end
24
+
25
+ end # ClassMethods
26
+
27
+ def refresh_git_repo(name)
28
+ EY.refresh_git_repo(name)
21
29
  end
30
+
31
+ def self.included(other)
32
+ other.extend ClassMethods
33
+ end
34
+
22
35
  end
23
36
  end
@@ -146,6 +146,11 @@ module EY
146
146
  @git_repo_setup[name] = setup
147
147
  end
148
148
 
149
+ def refresh_git_repo(name)
150
+ @git_repo_dir_cache ||= {}
151
+ @git_repo_dir_cache.delete name
152
+ end
153
+
149
154
  def git_repo_dir(name)
150
155
  @git_repo_dir_cache ||= {}
151
156
  return @git_repo_dir_cache[name] if @git_repo_dir_cache.has_key?(name)
@@ -43,8 +43,63 @@ shared_examples_for "it requires an unambiguous git repo" do
43
43
  run_ey({}, {:expect_failure => true})
44
44
  @err.should =~ /ambiguous/
45
45
  @err.should =~ /specify one of the following environments/
46
- @err.should =~ /giblets/
47
- @err.should =~ /keycollector_production/
46
+ @err.should =~ /giblets \(main\)/
47
+ @err.should =~ /keycollector_production \(main\)/
48
+ end
49
+ end
50
+
51
+ shared_examples_for "it takes an environment name and an app name and an account name" do
52
+ it_should_behave_like "it takes an app name"
53
+ it_should_behave_like "it takes an environment name"
54
+
55
+ context "when multiple accounts with collaboration" do
56
+ before :all do
57
+ api_scenario "two accounts, two apps, two environments, ambiguous"
58
+ end
59
+
60
+ it "fails when the app and environment are ambiguous across accounts" do
61
+ run_ey({:environment => "giblets", :app => "rails232app", :ref => 'master'}, {:expect_failure => true})
62
+ @err.should match(/Multiple app deployments possible/i)
63
+ @err.should match(/ey \S+ --environment='giblets' --app='rails232app' --account='account_2'/i)
64
+ @err.should match(/ey \S+ --environment='giblets' --app='rails232app' --account='main'/i)
65
+ end
66
+
67
+ it "runs when specifying the account disambiguates the app to deploy" do
68
+ run_ey({:environment => "giblets", :app => "rails232app", :account => "main", :ref => 'master'})
69
+ verify_ran(make_scenario({
70
+ :environment => 'giblets',
71
+ :application => 'rails232app',
72
+ :master_hostname => 'app_master_hostname.compute-1.amazonaws.com',
73
+ :ssh_username => 'turkey',
74
+ }))
75
+ end
76
+ end
77
+ end
78
+
79
+ shared_examples_for "it takes an environment name and an account name" do
80
+ it_should_behave_like "it takes an environment name"
81
+
82
+ context "when multiple accounts with collaboration" do
83
+ before :all do
84
+ api_scenario "two accounts, two apps, two environments, ambiguous"
85
+ end
86
+
87
+ it "fails when the app and environment are ambiguous across accounts" do
88
+ run_ey({:environment => "giblets"}, {:expect_failure => true})
89
+ @err.should match(/multiple environments possible/i)
90
+ @err.should match(/ey \S+ --environment='giblets' --account='account_2'/i)
91
+ @err.should match(/ey \S+ --environment='giblets' --account='main'/i)
92
+ end
93
+
94
+ it "runs when specifying the account disambiguates the app to deploy" do
95
+ run_ey({:environment => "giblets", :account => "main"})
96
+ verify_ran(make_scenario({
97
+ :environment => 'giblets',
98
+ :application => 'rails232app',
99
+ :master_hostname => 'app_master_hostname.compute-1.amazonaws.com',
100
+ :ssh_username => 'turkey',
101
+ }))
102
+ end
48
103
  end
49
104
  end
50
105
 
@@ -53,7 +108,7 @@ shared_examples_for "it takes an environment name" do
53
108
 
54
109
  it "operates on the current environment by default" do
55
110
  api_scenario "one app, one environment"
56
- run_ey({:env => nil}, {:debug => true})
111
+ run_ey({:environment => nil}, {:debug => true})
57
112
  verify_ran(make_scenario({
58
113
  :environment => 'giblets',
59
114
  :application => 'rails232app',
@@ -64,23 +119,47 @@ shared_examples_for "it takes an environment name" do
64
119
 
65
120
  it "complains when you specify a nonexistent environment" do
66
121
  api_scenario "one app, one environment"
67
- run_ey({:env => 'typo-happens-here'}, {:expect_failure => true})
122
+ run_ey({:environment => 'typo-happens-here'}, {:expect_failure => true})
68
123
  @err.should match(/no environment named 'typo-happens-here'/i)
69
124
  end
70
125
 
126
+ context "outside a git repo" do
127
+ define_git_repo("not actually a git repo") do |git_dir|
128
+ # in case we screw up and are not in a freshly-generated test
129
+ # git repository, don't blow away the thing we're developing
130
+ system("rm -rf .git") if `git remote -v`.include?("path/to/repo.git")
131
+ git_dir.join("cookbooks").mkdir
132
+ end
133
+
134
+ use_git_repo("not actually a git repo")
135
+
136
+ before :all do
137
+ api_scenario "one app, one environment"
138
+ end
139
+
140
+ it "works (and does not complain about git remotes)" do
141
+ run_ey({:environment => 'giblets'}) unless @takes_app_name
142
+ end
143
+
144
+ end
145
+
71
146
  context "given a piece of the environment name" do
72
147
  before(:all) do
73
148
  api_scenario "one app, many similarly-named environments"
74
149
  end
75
150
 
76
151
  it "complains when the substring is ambiguous" do
77
- run_ey({:env => 'staging'}, {:expect_failure => true})
78
- @err.should match(/'staging' is ambiguous/)
152
+ run_ey({:environment => 'staging'}, {:expect_failure => true})
153
+ if @takes_app_name
154
+ @err.should match(/multiple app deployments possible/i)
155
+ else
156
+ @err.should match(/multiple environments possible/i)
157
+ end
79
158
  end
80
159
 
81
160
  it "works when the substring is unambiguous" do
82
161
  api_scenario "one app, many similarly-named environments"
83
- run_ey({:env => 'prod'}, {:debug => true})
162
+ run_ey({:environment => 'prod'}, {:debug => true})
84
163
  verify_ran(make_scenario({
85
164
  :environment => 'railsapp_production',
86
165
  :application => 'rails232app',
@@ -92,18 +171,19 @@ shared_examples_for "it takes an environment name" do
92
171
 
93
172
  it "complains when it can't guess the environment and its name isn't specified" do
94
173
  api_scenario "one app, one environment, not linked"
95
- run_ey({:env => nil}, {:expect_failure => true})
96
- @err.should =~ /single environment/i
174
+ run_ey({:environment => nil}, {:expect_failure => true})
175
+ @err.should match(/there is no application configured/i)
97
176
  end
98
177
  end
99
178
 
100
179
  shared_examples_for "it takes an app name" do
101
180
  include Spec::Helpers::SharedIntegrationTestUtils
181
+ before { @takes_app_name = true }
102
182
 
103
183
  it "allows you to specify a valid app" do
104
184
  api_scenario "one app, one environment"
105
185
  Dir.chdir(Dir.tmpdir) do
106
- run_ey({:env => 'giblets', :app => 'rails232app', :ref => 'master'}, {})
186
+ run_ey({:environment => 'giblets', :app => 'rails232app', :ref => 'master'}, {})
107
187
  verify_ran(make_scenario({
108
188
  :environment => 'giblets',
109
189
  :application => 'rails232app',
@@ -128,7 +208,7 @@ shared_examples_for "it takes an app name" do
128
208
 
129
209
  it "complains when you specify a nonexistant app" do
130
210
  api_scenario "one app, one environment"
131
- run_ey({:env => 'giblets', :app => 'P-time-SAT-solver', :ref => 'master'},
211
+ run_ey({:environment => 'giblets', :app => 'P-time-SAT-solver', :ref => 'master'},
132
212
  {:expect_failure => true})
133
213
  @err.should =~ /no app.*P-time-SAT-solver/i
134
214
  end
@@ -141,7 +221,7 @@ shared_examples_for "it invokes engineyard-serverside" do
141
221
  context "with arguments" do
142
222
  before(:all) do
143
223
  api_scenario "one app, one environment"
144
- run_ey({:env => 'giblets', :verbose => true})
224
+ run_ey({:environment => 'giblets', :verbose => true})
145
225
  end
146
226
 
147
227
  it "passes --verbose to engineyard-serverside" do
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: engineyard
3
3
  version: !ruby/object:Gem::Version
4
- hash: 25
4
+ hash: 31
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
8
  - 3
9
- - 1
10
- version: 1.3.1
9
+ - 2
10
+ version: 1.3.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - EY Cloud Team
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-09-20 00:00:00 -07:00
18
+ date: 2010-10-15 00:00:00 -07:00
19
19
  default_executable: ey
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -24,12 +24,12 @@ dependencies:
24
24
  requirements:
25
25
  - - ~>
26
26
  - !ruby/object:Gem::Version
27
- hash: 39
27
+ hash: 33
28
28
  segments:
29
29
  - 0
30
30
  - 14
31
- - 0
32
- version: 0.14.0
31
+ - 3
32
+ version: 0.14.3
33
33
  requirement: *id001
34
34
  type: :runtime
35
35
  name: thor
@@ -77,24 +77,10 @@ dependencies:
77
77
  version: "0"
78
78
  requirement: *id004
79
79
  type: :runtime
80
- name: ruby-termios
81
- prerelease: false
82
- - !ruby/object:Gem::Dependency
83
- version_requirements: &id005 !ruby/object:Gem::Requirement
84
- none: false
85
- requirements:
86
- - - ">="
87
- - !ruby/object:Gem::Version
88
- hash: 3
89
- segments:
90
- - 0
91
- version: "0"
92
- requirement: *id005
93
- type: :runtime
94
80
  name: json_pure
95
81
  prerelease: false
96
82
  - !ruby/object:Gem::Dependency
97
- version_requirements: &id006 !ruby/object:Gem::Requirement
83
+ version_requirements: &id005 !ruby/object:Gem::Requirement
98
84
  none: false
99
85
  requirements:
100
86
  - - ~>
@@ -105,23 +91,23 @@ dependencies:
105
91
  - 0
106
92
  - 4
107
93
  version: 0.0.4
108
- requirement: *id006
94
+ requirement: *id005
109
95
  type: :runtime
110
96
  name: escape
111
97
  prerelease: false
112
98
  - !ruby/object:Gem::Dependency
113
- version_requirements: &id007 !ruby/object:Gem::Requirement
99
+ version_requirements: &id006 !ruby/object:Gem::Requirement
114
100
  none: false
115
101
  requirements:
116
102
  - - "="
117
103
  - !ruby/object:Gem::Version
118
- hash: 29
104
+ hash: 17
119
105
  segments:
120
106
  - 1
121
107
  - 3
122
- - 3
123
- version: 1.3.3
124
- requirement: *id007
108
+ - 5
109
+ version: 1.3.5
110
+ requirement: *id006
125
111
  type: :runtime
126
112
  name: engineyard-serverside-adapter
127
113
  prerelease: false
@@ -147,6 +133,7 @@ files:
147
133
  - lib/engineyard/collection.rb
148
134
  - lib/engineyard/config.rb
149
135
  - lib/engineyard/error.rb
136
+ - lib/engineyard/model/account.rb
150
137
  - lib/engineyard/model/api_struct.rb
151
138
  - lib/engineyard/model/app.rb
152
139
  - lib/engineyard/model/environment.rb
@@ -154,6 +141,7 @@ files:
154
141
  - lib/engineyard/model/log.rb
155
142
  - lib/engineyard/model.rb
156
143
  - lib/engineyard/repo.rb
144
+ - lib/engineyard/resolver.rb
157
145
  - lib/engineyard/ruby_ext.rb
158
146
  - lib/engineyard/thor.rb
159
147
  - lib/engineyard/version.rb
@@ -170,6 +158,7 @@ files:
170
158
  - spec/engineyard/model/environment_spec.rb
171
159
  - spec/engineyard/model/instance_spec.rb
172
160
  - spec/engineyard/repo_spec.rb
161
+ - spec/engineyard/resolver_spec.rb
173
162
  - spec/engineyard_spec.rb
174
163
  - spec/ey/deploy_spec.rb
175
164
  - spec/ey/ey_spec.rb
@@ -235,6 +224,7 @@ test_files:
235
224
  - spec/engineyard/model/environment_spec.rb
236
225
  - spec/engineyard/model/instance_spec.rb
237
226
  - spec/engineyard/repo_spec.rb
227
+ - spec/engineyard/resolver_spec.rb
238
228
  - spec/engineyard_spec.rb
239
229
  - spec/ey/deploy_spec.rb
240
230
  - spec/ey/ey_spec.rb