vmc 0.4.0.beta.20 → 0.4.0.beta.21
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/vmc-ng/Rakefile +41 -5
- data/vmc-ng/lib/vmc/cli/app.rb +7 -3
- data/vmc-ng/lib/vmc/cli/start.rb +111 -72
- data/vmc-ng/lib/vmc/cli.rb +63 -15
- data/vmc-ng/lib/vmc/version.rb +1 -1
- data/vmc-ng/spec/Rakefile +14 -0
- data/vmc-ng/spec/app/apps_spec.rb +75 -0
- data/vmc-ng/spec/helpers.rb +103 -0
- data/vmc-ng/spec/start/target_spec.rb +34 -0
- metadata +42 -10
data/vmc-ng/Rakefile
CHANGED
@@ -1,11 +1,47 @@
|
|
1
|
-
require "
|
1
|
+
require "rake"
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
end
|
3
|
+
$LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
|
4
|
+
require "vmc/version"
|
6
5
|
|
7
6
|
task :default => :spec
|
8
7
|
|
9
|
-
|
8
|
+
desc "Run specs"
|
9
|
+
task :spec => ["bundler:install", "test:spec"]
|
10
|
+
|
11
|
+
desc "Run integration tests"
|
12
|
+
task :test => ["bundler:install", "test:integration"]
|
13
|
+
|
14
|
+
task :build do
|
15
|
+
sh "gem build vmc.gemspec"
|
16
|
+
end
|
17
|
+
|
18
|
+
task :install => :build do
|
19
|
+
sh "gem install --local vmc-#{VMC::VERSION}"
|
20
|
+
end
|
21
|
+
|
22
|
+
task :uninstall do
|
23
|
+
sh "gem uninstall vmc"
|
24
|
+
end
|
25
|
+
|
26
|
+
task :reinstall => [:uninstall, :install]
|
27
|
+
|
28
|
+
task :release => :build do
|
29
|
+
sh "gem push vmc-#{VMC::VERSION}.gem"
|
30
|
+
end
|
31
|
+
|
32
|
+
namespace "bundler" do
|
33
|
+
desc "Install gems"
|
34
|
+
task "install" do
|
35
|
+
sh("bundle install")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
namespace "test" do
|
40
|
+
task "spec" do |t|
|
41
|
+
# nothing
|
42
|
+
end
|
10
43
|
|
44
|
+
task "integration" do |t|
|
45
|
+
sh("cd spec && bundle exec rake spec")
|
46
|
+
end
|
11
47
|
end
|
data/vmc-ng/lib/vmc/cli/app.rb
CHANGED
@@ -43,13 +43,17 @@ module VMC
|
|
43
43
|
|
44
44
|
desc "List your applications"
|
45
45
|
group :apps
|
46
|
+
input :space, :desc => "Show apps in given space",
|
47
|
+
:from_given => proc { |name|
|
48
|
+
client.space_by_name(name) || \
|
49
|
+
fail("Unknown space '#{name}'")
|
50
|
+
}
|
46
51
|
input :name, :desc => "Filter by name regexp"
|
47
52
|
input :runtime, :desc => "Filter by runtime regexp"
|
48
53
|
input :framework, :desc => "Filter by framework regexp"
|
49
54
|
input :url, :desc => "Filter by url regexp"
|
50
55
|
def apps(input)
|
51
|
-
if
|
52
|
-
space = client.current_space
|
56
|
+
if space = input[:space] || client.current_space
|
53
57
|
apps =
|
54
58
|
with_progress("Getting applications in #{c(space.name, :name)}") do
|
55
59
|
space.apps
|
@@ -146,7 +150,7 @@ module VMC
|
|
146
150
|
|
147
151
|
app = client.app
|
148
152
|
app.name = name
|
149
|
-
app.space = client.current_space if
|
153
|
+
app.space = client.current_space if client.current_space
|
150
154
|
app.total_instances = input[:instances]
|
151
155
|
|
152
156
|
detector = Detector.new(client, path)
|
data/vmc-ng/lib/vmc/cli/start.rb
CHANGED
@@ -9,6 +9,19 @@ module VMC
|
|
9
9
|
@@displayed_target
|
10
10
|
end
|
11
11
|
|
12
|
+
|
13
|
+
# These commands don't require authentication.
|
14
|
+
def precondition; end
|
15
|
+
|
16
|
+
|
17
|
+
def self.find_by_name(what)
|
18
|
+
proc { |name, choices|
|
19
|
+
choices.find { |c| c.name == name } ||
|
20
|
+
fail("Unknown #{what} '#{name}'")
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
|
12
25
|
desc "Display information on the current target, user, etc."
|
13
26
|
group :start
|
14
27
|
input :runtimes, :type => :boolean,
|
@@ -57,7 +70,7 @@ module VMC
|
|
57
70
|
|
58
71
|
if user = client.current_user
|
59
72
|
puts ""
|
60
|
-
puts "user: #{b(user.email || user.
|
73
|
+
puts "user: #{b(user.email || user.guid)}"
|
61
74
|
end
|
62
75
|
end
|
63
76
|
|
@@ -104,21 +117,25 @@ module VMC
|
|
104
117
|
end
|
105
118
|
end
|
106
119
|
|
107
|
-
|
108
120
|
desc "Set or display the current target cloud"
|
109
121
|
group :start
|
110
122
|
input :url, :argument => :optional,
|
111
123
|
:desc => "Target URL to switch to"
|
124
|
+
input(:interactive, :alias => "-i", :type => :boolean,
|
125
|
+
:desc => "Interactively select organization/space")
|
112
126
|
input(:organization, :aliases => ["--org", "-o"],
|
113
|
-
:
|
114
|
-
|
127
|
+
:from_given => find_by_name("organization"),
|
128
|
+
:desc => "Organization") { |orgs|
|
129
|
+
ask("Organization", :choices => orgs, :display => proc(&:name))
|
115
130
|
}
|
116
|
-
input(:space, :alias => "-s",
|
117
|
-
|
131
|
+
input(:space, :alias => "-s",
|
132
|
+
:from_given => find_by_name("space"),
|
133
|
+
:desc => "Space") { |spaces|
|
134
|
+
ask("Space", :choices => spaces, :display => proc(&:name))
|
118
135
|
}
|
119
136
|
def target(input)
|
120
|
-
if !input
|
121
|
-
!input.given?(:space)
|
137
|
+
if !input[:interactive] && !input.given?(:url) &&
|
138
|
+
!input.given?(:organization) && !input.given?(:space)
|
122
139
|
display_target
|
123
140
|
return
|
124
141
|
end
|
@@ -130,22 +147,22 @@ module VMC
|
|
130
147
|
set_target(target)
|
131
148
|
end
|
132
149
|
|
133
|
-
|
150
|
+
unless quiet?
|
151
|
+
puts ""
|
152
|
+
display_org_and_space
|
153
|
+
end
|
134
154
|
end
|
135
155
|
|
136
|
-
return unless v2?
|
137
|
-
|
138
|
-
unless client.logged_in?
|
139
|
-
puts "" unless quiet?
|
140
|
-
invoke :login
|
141
|
-
@client = nil
|
142
|
-
end
|
156
|
+
return unless v2? && client.logged_in?
|
143
157
|
|
144
|
-
|
158
|
+
if input[:interactive] || input.given?(:organization) ||
|
159
|
+
input.given?(:space)
|
160
|
+
info = target_info
|
145
161
|
|
146
|
-
|
162
|
+
select_org_and_space(input, info)
|
147
163
|
|
148
|
-
|
164
|
+
save_target_info(info)
|
165
|
+
end
|
149
166
|
end
|
150
167
|
|
151
168
|
|
@@ -159,34 +176,22 @@ module VMC
|
|
159
176
|
end
|
160
177
|
|
161
178
|
|
162
|
-
def ask_prompt(type, label)
|
163
|
-
if type == "password"
|
164
|
-
options = { :echo => "*", :forget => true }
|
165
|
-
else
|
166
|
-
options = {}
|
167
|
-
end
|
168
|
-
|
169
|
-
ask(label, options)
|
170
|
-
end
|
171
|
-
|
172
|
-
def ask_prompts(credentials, prompts)
|
173
|
-
prompts.each do |name, meta|
|
174
|
-
type, label = meta
|
175
|
-
credentials[name] ||= ask_prompt(type, label)
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
179
|
desc "Authenticate with the target"
|
180
180
|
group :start
|
181
181
|
input :username, :alias => "--email", :argument => :optional,
|
182
182
|
:desc => "Account email"
|
183
183
|
input :password, :desc => "Account password"
|
184
|
+
input(:interactive, :alias => "-i", :type => :boolean,
|
185
|
+
:desc => "Interactively select organization/space")
|
184
186
|
input(:organization, :aliases => ["--org", "-o"],
|
185
|
-
:
|
186
|
-
|
187
|
+
:from_given => find_by_name("organization"),
|
188
|
+
:desc => "Organization") { |orgs|
|
189
|
+
ask("Organization", :choices => orgs, :display => proc(&:name))
|
187
190
|
}
|
188
|
-
input(:space, :alias => "-s",
|
189
|
-
|
191
|
+
input(:space, :alias => "-s",
|
192
|
+
:from_given => find_by_name("space"),
|
193
|
+
:desc => "Space") { |spaces|
|
194
|
+
ask("Space", :choices => spaces, :display => proc(&:name))
|
190
195
|
}
|
191
196
|
def login(input)
|
192
197
|
display_target unless quiet?
|
@@ -228,9 +233,14 @@ module VMC
|
|
228
233
|
end
|
229
234
|
end
|
230
235
|
|
231
|
-
select_org_and_space(input, info) if v2?
|
232
|
-
|
233
236
|
save_target_info(info)
|
237
|
+
invalidate_client
|
238
|
+
|
239
|
+
if v2?
|
240
|
+
puts "" if input[:interactive]
|
241
|
+
select_org_and_space(input, info)
|
242
|
+
save_target_info(info)
|
243
|
+
end
|
234
244
|
ensure
|
235
245
|
exit_status 1 if not authenticated
|
236
246
|
end
|
@@ -288,18 +298,31 @@ module VMC
|
|
288
298
|
|
289
299
|
private
|
290
300
|
|
301
|
+
def ask_prompt(type, label)
|
302
|
+
if type == "password"
|
303
|
+
options = { :echo => "*", :forget => true }
|
304
|
+
else
|
305
|
+
options = {}
|
306
|
+
end
|
307
|
+
|
308
|
+
ask(label, options)
|
309
|
+
end
|
310
|
+
|
311
|
+
def ask_prompts(credentials, prompts)
|
312
|
+
prompts.each do |name, meta|
|
313
|
+
type, label = meta
|
314
|
+
credentials[name] ||= ask_prompt(type, label)
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
291
318
|
def display_target
|
292
|
-
return if
|
319
|
+
return if displayed_target?
|
293
320
|
|
294
321
|
if quiet?
|
295
322
|
puts client.target
|
296
323
|
else
|
297
|
-
puts "
|
298
|
-
|
299
|
-
if v2? && client.current_organization && client.current_space
|
300
|
-
puts "Organization: #{c(client.current_organization.name, :name)}"
|
301
|
-
puts "Space: #{c(client.current_space.name, :name)}"
|
302
|
-
end
|
324
|
+
puts "target: #{c(client.target, :name)}"
|
325
|
+
display_org_and_space
|
303
326
|
end
|
304
327
|
|
305
328
|
puts ""
|
@@ -307,6 +330,19 @@ module VMC
|
|
307
330
|
@@displayed_target = true
|
308
331
|
end
|
309
332
|
|
333
|
+
def display_org_and_space
|
334
|
+
return unless v2?
|
335
|
+
|
336
|
+
if org = client.current_organization
|
337
|
+
puts "organization: #{c(org.name, :name)}"
|
338
|
+
end
|
339
|
+
|
340
|
+
if space = client.current_space
|
341
|
+
puts "space: #{c(space.name, :name)}"
|
342
|
+
end
|
343
|
+
rescue CFoundry::APIError
|
344
|
+
end
|
345
|
+
|
310
346
|
def display_runtime(r)
|
311
347
|
if quiet?
|
312
348
|
puts r.name
|
@@ -346,56 +382,59 @@ module VMC
|
|
346
382
|
end
|
347
383
|
end
|
348
384
|
|
349
|
-
def org_valid?(
|
350
|
-
return false unless
|
351
|
-
client.organization(
|
385
|
+
def org_valid?(guid, user = client.current_user)
|
386
|
+
return false unless guid
|
387
|
+
client.organization(guid).users.include? user
|
352
388
|
rescue CFoundry::APIError
|
353
389
|
false
|
354
390
|
end
|
355
391
|
|
356
|
-
def space_valid?(
|
357
|
-
return false unless
|
358
|
-
client.space(
|
392
|
+
def space_valid?(guid, user = client.current_user)
|
393
|
+
return false unless guid
|
394
|
+
client.space(guid).developers.include? user
|
359
395
|
rescue CFoundry::APIError
|
360
396
|
false
|
361
397
|
end
|
362
398
|
|
363
399
|
def select_org_and_space(input, info)
|
364
|
-
|
400
|
+
changed_org = false
|
401
|
+
|
402
|
+
if input[:interactive] || input.given?(:organization) || \
|
403
|
+
!org_valid?(info[:organization])
|
365
404
|
orgs = client.organizations
|
366
405
|
fail "No organizations!" if orgs.empty?
|
367
406
|
|
368
|
-
if orgs.size == 1 && !input.given?(:organization)
|
407
|
+
if !input[:interactive] && orgs.size == 1 && !input.given?(:organization)
|
369
408
|
org = orgs.first
|
370
409
|
else
|
371
|
-
|
372
|
-
org = orgs.find { |o| o.name == org_name }
|
373
|
-
fail "Unknown organization '#{org_name}'" unless org
|
410
|
+
org = input[:organization, orgs.sort_by(&:name)]
|
374
411
|
end
|
375
412
|
|
376
|
-
|
413
|
+
with_progress("Switching to organization #{c(org.name, :name)}") do
|
414
|
+
info[:organization] = org.guid
|
415
|
+
changed_org = true
|
416
|
+
end
|
377
417
|
else
|
378
418
|
org = client.current_organization
|
379
419
|
end
|
380
420
|
|
381
|
-
# switching org
|
382
|
-
if input
|
383
|
-
|
384
|
-
spaces =
|
385
|
-
s.organization.id == org.id
|
386
|
-
end
|
421
|
+
# switching org means switching space
|
422
|
+
if input[:interactive] || changed_org || input.given?(:space) || \
|
423
|
+
!space_valid?(info[:space])
|
424
|
+
spaces = org.spaces
|
387
425
|
|
388
426
|
fail "No spaces!" if spaces.empty?
|
389
427
|
|
390
|
-
if spaces.size == 1 && !input.given?(:space)
|
428
|
+
if !input[:interactive] && spaces.size == 1 && !input.given?(:space)
|
391
429
|
space = spaces.first
|
392
430
|
else
|
393
|
-
|
394
|
-
space = spaces.
|
395
|
-
fail "Unknown space '#{space_name}'" unless space
|
431
|
+
puts "" if changed_org
|
432
|
+
space = input[:space, spaces.sort_by(&:name)]
|
396
433
|
end
|
397
434
|
|
398
|
-
|
435
|
+
with_progress("Switching to space #{c(space.name, :name)}") do
|
436
|
+
info[:space] = space.guid
|
437
|
+
end
|
399
438
|
end
|
400
439
|
end
|
401
440
|
end
|
data/vmc-ng/lib/vmc/cli.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
require "yaml"
|
2
|
+
require "socket"
|
3
|
+
require "net/http"
|
2
4
|
|
3
5
|
require "mothership"
|
4
6
|
require "mothership/pretty"
|
@@ -62,10 +64,27 @@ module VMC
|
|
62
64
|
end
|
63
65
|
end
|
64
66
|
|
67
|
+
def precondition
|
68
|
+
unless client.logged_in?
|
69
|
+
fail "Please log in with 'vmc login'."
|
70
|
+
end
|
71
|
+
|
72
|
+
return unless v2?
|
73
|
+
|
74
|
+
unless client.current_organization
|
75
|
+
fail "Please select an organization with 'vmc target -i'."
|
76
|
+
end
|
77
|
+
|
78
|
+
unless client.current_space
|
79
|
+
fail "Please select a space with 'vmc target -i'."
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
65
83
|
def execute(cmd, argv)
|
66
84
|
if option(:help)
|
67
85
|
invoke :help, :command => cmd.name.to_s
|
68
86
|
else
|
87
|
+
cmd.context.new.precondition if cmd.context <= CLI
|
69
88
|
super
|
70
89
|
end
|
71
90
|
rescue Interrupt
|
@@ -82,18 +101,27 @@ module VMC
|
|
82
101
|
puts c("Not authenticated! Try logging in:", :warning)
|
83
102
|
|
84
103
|
invoke :login
|
85
|
-
@client = nil
|
86
104
|
|
87
105
|
retry
|
88
106
|
end
|
89
107
|
|
108
|
+
log_error(e)
|
109
|
+
|
90
110
|
err "Denied: #{e.description}"
|
111
|
+
|
91
112
|
rescue Exception => e
|
113
|
+
ensure_config_dir
|
114
|
+
|
115
|
+
log_error(e)
|
116
|
+
|
92
117
|
msg = e.class.name
|
93
118
|
msg << ": #{e}" unless e.to_s.empty?
|
94
119
|
err msg
|
120
|
+
end
|
95
121
|
|
96
|
-
|
122
|
+
def log_error(e)
|
123
|
+
msg = e.class.name
|
124
|
+
msg << ": #{e}" unless e.to_s.empty?
|
97
125
|
|
98
126
|
File.open(File.expand_path(VMC::CRASH_FILE), "w") do |f|
|
99
127
|
f.puts "Time of crash:"
|
@@ -125,14 +153,14 @@ module VMC
|
|
125
153
|
option(:color)
|
126
154
|
end
|
127
155
|
|
128
|
-
def err(msg,
|
156
|
+
def err(msg, status = 1)
|
129
157
|
if quiet?
|
130
158
|
$stderr.puts(msg)
|
131
159
|
else
|
132
160
|
puts c(msg, :error)
|
133
161
|
end
|
134
162
|
|
135
|
-
exit_status
|
163
|
+
exit_status status
|
136
164
|
end
|
137
165
|
|
138
166
|
def fail(msg)
|
@@ -141,7 +169,12 @@ module VMC
|
|
141
169
|
|
142
170
|
def sane_target_url(url)
|
143
171
|
unless url =~ /^https?:\/\//
|
144
|
-
|
172
|
+
begin
|
173
|
+
TCPSocket.new(url, Net::HTTP.https_default_port)
|
174
|
+
url = "https://#{url}"
|
175
|
+
rescue SocketError, Timeout::Error
|
176
|
+
url = "http://#{url}"
|
177
|
+
end
|
145
178
|
end
|
146
179
|
|
147
180
|
url.gsub(/\/$/, "")
|
@@ -180,7 +213,7 @@ module VMC
|
|
180
213
|
f.write(sane_target_url(url))
|
181
214
|
end
|
182
215
|
|
183
|
-
|
216
|
+
invalidate_client
|
184
217
|
end
|
185
218
|
|
186
219
|
def targets_info
|
@@ -221,7 +254,7 @@ module VMC
|
|
221
254
|
end
|
222
255
|
|
223
256
|
def remove_target_info
|
224
|
-
ts =
|
257
|
+
ts = targets_info
|
225
258
|
ts.delete client_target
|
226
259
|
save_targets(ts)
|
227
260
|
end
|
@@ -234,12 +267,17 @@ module VMC
|
|
234
267
|
client.is_a?(CFoundry::V2::Client)
|
235
268
|
end
|
236
269
|
|
270
|
+
def invalidate_client
|
271
|
+
@@client = nil
|
272
|
+
client
|
273
|
+
end
|
274
|
+
|
237
275
|
def client
|
238
|
-
return
|
276
|
+
return @@client if defined?(@@client) && @@client
|
239
277
|
|
240
278
|
info = target_info
|
241
279
|
|
242
|
-
|
280
|
+
@@client =
|
243
281
|
case info[:version]
|
244
282
|
when 2
|
245
283
|
CFoundry::V2::Client.new(client_target, info[:token])
|
@@ -249,11 +287,11 @@ module VMC
|
|
249
287
|
CFoundry::Client.new(client_target, info[:token])
|
250
288
|
end
|
251
289
|
|
252
|
-
|
253
|
-
|
290
|
+
@@client.proxy = option(:proxy)
|
291
|
+
@@client.trace = option(:trace)
|
254
292
|
|
255
293
|
info[:version] ||=
|
256
|
-
case
|
294
|
+
case @@client
|
257
295
|
when CFoundry::V2::Client
|
258
296
|
2
|
259
297
|
else
|
@@ -261,16 +299,26 @@ module VMC
|
|
261
299
|
end
|
262
300
|
|
263
301
|
if org = info[:organization]
|
264
|
-
|
302
|
+
@@client.current_organization = @@client.organization(org)
|
265
303
|
end
|
266
304
|
|
267
305
|
if space = info[:space]
|
268
|
-
|
306
|
+
@@client.current_space = @@client.space(space)
|
269
307
|
end
|
270
308
|
|
271
309
|
save_target_info(info)
|
272
310
|
|
273
|
-
|
311
|
+
@@client
|
312
|
+
end
|
313
|
+
|
314
|
+
class << self
|
315
|
+
def client
|
316
|
+
@@client
|
317
|
+
end
|
318
|
+
|
319
|
+
def client=(c)
|
320
|
+
@@client = c
|
321
|
+
end
|
274
322
|
end
|
275
323
|
end
|
276
324
|
end
|
data/vmc-ng/lib/vmc/version.rb
CHANGED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
Bundler.require(:default, :development)
|
4
|
+
|
5
|
+
require 'rake/dsl_definition'
|
6
|
+
require 'rake'
|
7
|
+
require 'rspec'
|
8
|
+
require 'rspec/core/rake_task'
|
9
|
+
|
10
|
+
RSpec::Core::RakeTask.new do |t|
|
11
|
+
t.pattern = "**/*_spec.rb"
|
12
|
+
t.rspec_opts = ["--format", "documentation", "--colour"]
|
13
|
+
end
|
14
|
+
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require "./helpers"
|
2
|
+
|
3
|
+
describe "App#apps" do
|
4
|
+
it "lists app names" do
|
5
|
+
with_random_apps do |apps|
|
6
|
+
shell("apps").split("\n").should =~
|
7
|
+
apps.collect(&:name)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
it "filters by name with --name" do
|
12
|
+
with_random_apps do |apps|
|
13
|
+
app = apps[rand(apps.size)]
|
14
|
+
|
15
|
+
result = shell("apps", "--name", app.name).split("\n")
|
16
|
+
result.should =~ [app.name]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it "filters by runtime with --runtime" do
|
21
|
+
with_random_apps do |apps|
|
22
|
+
app = apps[rand(apps.size)]
|
23
|
+
|
24
|
+
result = shell("apps", "--runtime", app.runtime.name).split("\n")
|
25
|
+
actual =
|
26
|
+
apps.select { |a|
|
27
|
+
/#{app.runtime.name}/ =~ a.runtime.name
|
28
|
+
}.collect(&:name)
|
29
|
+
|
30
|
+
result.should =~ actual
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
it "filters by framework with --framework" do
|
35
|
+
with_random_apps do |apps|
|
36
|
+
app = apps[rand(apps.size)]
|
37
|
+
|
38
|
+
result = shell("apps", "--framework", app.framework.name).split("\n")
|
39
|
+
actual =
|
40
|
+
apps.select { |a|
|
41
|
+
/#{app.framework.name}/ =~ a.framework.name
|
42
|
+
}.collect(&:name)
|
43
|
+
|
44
|
+
result.should =~ actual
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# TODO: use space other than current
|
49
|
+
it "can be told which space with --space" do
|
50
|
+
with_random_apps do |apps|
|
51
|
+
app = apps[rand(apps.size)]
|
52
|
+
|
53
|
+
result = shell("apps", "--space", client.current_space.name).split("\n")
|
54
|
+
actual = client.current_space.apps.collect(&:name)
|
55
|
+
|
56
|
+
result.should =~ actual
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# TODO: v2
|
61
|
+
#it "filters by url with --url" do
|
62
|
+
#with_random_apps do |apps|
|
63
|
+
#app = apps[rand(apps.size)]
|
64
|
+
#url = app.urls[rand(app.urls.size)]
|
65
|
+
|
66
|
+
#result = shell("apps", "--url", url).split("\n")
|
67
|
+
#actual =
|
68
|
+
#apps.select { |a|
|
69
|
+
#a.urls.include? url
|
70
|
+
#}.collect(&:name)
|
71
|
+
|
72
|
+
#result.should =~ actual
|
73
|
+
#end
|
74
|
+
#end
|
75
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require "cfoundry"
|
2
|
+
require "vmc"
|
3
|
+
|
4
|
+
TARGET = ENV["VMC_TEST_TARGET"] || "http://localhost:8181"
|
5
|
+
USER = ENV["VMC_TEST_USER"] || "sre@vmware.com"
|
6
|
+
PASSWORD = ENV["VMC_TEST_PASSWORD"] || "test"
|
7
|
+
|
8
|
+
module VMCHelpers
|
9
|
+
def random_str
|
10
|
+
format("%x", rand(1000000))
|
11
|
+
end
|
12
|
+
|
13
|
+
def client
|
14
|
+
VMC::CLI.client
|
15
|
+
end
|
16
|
+
|
17
|
+
# invoke a block while logged out
|
18
|
+
def without_auth
|
19
|
+
proxy = client.proxy
|
20
|
+
client.logout
|
21
|
+
client.proxy = nil
|
22
|
+
yield
|
23
|
+
ensure
|
24
|
+
client.login(USER, PASSWORD)
|
25
|
+
client.proxy = proxy
|
26
|
+
end
|
27
|
+
|
28
|
+
# same as Ruby 1.9's Array#sample
|
29
|
+
def sample(ary)
|
30
|
+
ary[rand(ary.size)]
|
31
|
+
end
|
32
|
+
|
33
|
+
# cache frameworks for app generation
|
34
|
+
def frameworks
|
35
|
+
@@frameworks ||= client.frameworks(0)
|
36
|
+
end
|
37
|
+
|
38
|
+
# cache runtimes for app generation
|
39
|
+
def runtimes
|
40
|
+
@@runtimes ||= client.runtimes(0)
|
41
|
+
end
|
42
|
+
|
43
|
+
def with_random_app
|
44
|
+
with_random_apps(1)
|
45
|
+
end
|
46
|
+
|
47
|
+
# create 2-5 random apps, call the block, and then delete them
|
48
|
+
def with_random_apps(num = rand(3) + 2)
|
49
|
+
apps = []
|
50
|
+
|
51
|
+
num.times do |n|
|
52
|
+
app = client.app
|
53
|
+
app.name = "app-#{n + 1}-#{random_str}"
|
54
|
+
app.space = client.current_space
|
55
|
+
app.instances = rand(2)
|
56
|
+
|
57
|
+
app.framework = sample(frameworks)
|
58
|
+
app.runtime = sample(runtimes)
|
59
|
+
app.memory = sample([64, 128, 256, 512])
|
60
|
+
app.create!
|
61
|
+
|
62
|
+
apps << app
|
63
|
+
end
|
64
|
+
|
65
|
+
yield apps
|
66
|
+
ensure
|
67
|
+
apps.each(&:delete!)
|
68
|
+
end
|
69
|
+
|
70
|
+
# invoke a command with a given arglist
|
71
|
+
def shell(*argv)
|
72
|
+
before_out = $stdout
|
73
|
+
before_err = $stderr
|
74
|
+
|
75
|
+
$stdout = StringIO.new
|
76
|
+
$stderr = StringIO.new
|
77
|
+
|
78
|
+
begin
|
79
|
+
VMC::CLI.start(argv)
|
80
|
+
rescue SystemExit => e
|
81
|
+
unless e.status == 0
|
82
|
+
raise "execution failed! output:\n#{$stderr.string}"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
$stdout.string
|
87
|
+
ensure
|
88
|
+
$stdout = before_out
|
89
|
+
$stderr = before_err
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
RSpec.configure do |c|
|
94
|
+
c.include VMCHelpers
|
95
|
+
|
96
|
+
c.before(:all) do
|
97
|
+
VMC::CLI.client = CFoundry::Client.new(TARGET)
|
98
|
+
|
99
|
+
client.login(:username => USER, :password => PASSWORD)
|
100
|
+
client.current_organization = client.organizations.first
|
101
|
+
client.current_space = client.current_organization.spaces.first
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require "./helpers"
|
2
|
+
|
3
|
+
describe "Start#target" do
|
4
|
+
it "shows target url with no arguments" do
|
5
|
+
shell("target").rstrip.should == client.target
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "switching target url" do
|
9
|
+
before(:each) do
|
10
|
+
@old_client = client
|
11
|
+
end
|
12
|
+
|
13
|
+
after(:each) do
|
14
|
+
VMC::CLI.client = @old_client
|
15
|
+
end
|
16
|
+
|
17
|
+
it "switches target url if given one argument" do
|
18
|
+
shell("target", "http://api.cloudfoundry.com")
|
19
|
+
client.target.should == "http://api.cloudfoundry.com"
|
20
|
+
end
|
21
|
+
|
22
|
+
it "defaults to https if supported by remote" do
|
23
|
+
shell("target", "api.cloudfoundry.com")
|
24
|
+
client.target.should == "https://api.cloudfoundry.com"
|
25
|
+
end
|
26
|
+
|
27
|
+
# TODO: this assumes locally running cc without https support
|
28
|
+
it "defaults to http if not supported by remote" do
|
29
|
+
base_target = client.target.sub(/^https?:\/\//, "")
|
30
|
+
shell("target", base_target)
|
31
|
+
client.target.should == "http://#{base_target}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vmc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 62196425
|
5
5
|
prerelease: 6
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 4
|
9
9
|
- 0
|
10
10
|
- beta
|
11
|
-
-
|
12
|
-
version: 0.4.0.beta.
|
11
|
+
- 21
|
12
|
+
version: 0.4.0.beta.21
|
13
13
|
platform: ruby
|
14
14
|
authors:
|
15
15
|
- VMware
|
@@ -17,7 +17,7 @@ autorequire:
|
|
17
17
|
bindir: bin
|
18
18
|
cert_chain: []
|
19
19
|
|
20
|
-
date: 2012-07-
|
20
|
+
date: 2012-07-19 00:00:00 Z
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|
23
23
|
name: json_pure
|
@@ -249,12 +249,12 @@ dependencies:
|
|
249
249
|
requirements:
|
250
250
|
- - ~>
|
251
251
|
- !ruby/object:Gem::Version
|
252
|
-
hash:
|
252
|
+
hash: 3
|
253
253
|
segments:
|
254
254
|
- 0
|
255
255
|
- 3
|
256
|
-
-
|
257
|
-
version: 0.3.
|
256
|
+
- 8
|
257
|
+
version: 0.3.8
|
258
258
|
type: :runtime
|
259
259
|
version_requirements: *id014
|
260
260
|
- !ruby/object:Gem::Dependency
|
@@ -265,12 +265,12 @@ dependencies:
|
|
265
265
|
requirements:
|
266
266
|
- - ~>
|
267
267
|
- !ruby/object:Gem::Version
|
268
|
-
hash:
|
268
|
+
hash: 15
|
269
269
|
segments:
|
270
270
|
- 0
|
271
271
|
- 0
|
272
|
-
-
|
273
|
-
version: 0.0.
|
272
|
+
- 8
|
273
|
+
version: 0.0.8
|
274
274
|
type: :runtime
|
275
275
|
version_requirements: *id015
|
276
276
|
- !ruby/object:Gem::Dependency
|
@@ -289,6 +289,34 @@ dependencies:
|
|
289
289
|
version: 0.3.1
|
290
290
|
type: :runtime
|
291
291
|
version_requirements: *id016
|
292
|
+
- !ruby/object:Gem::Dependency
|
293
|
+
name: rake
|
294
|
+
prerelease: false
|
295
|
+
requirement: &id017 !ruby/object:Gem::Requirement
|
296
|
+
none: false
|
297
|
+
requirements:
|
298
|
+
- - ">="
|
299
|
+
- !ruby/object:Gem::Version
|
300
|
+
hash: 3
|
301
|
+
segments:
|
302
|
+
- 0
|
303
|
+
version: "0"
|
304
|
+
type: :runtime
|
305
|
+
version_requirements: *id017
|
306
|
+
- !ruby/object:Gem::Dependency
|
307
|
+
name: rspec
|
308
|
+
prerelease: false
|
309
|
+
requirement: &id018 !ruby/object:Gem::Requirement
|
310
|
+
none: false
|
311
|
+
requirements:
|
312
|
+
- - ">="
|
313
|
+
- !ruby/object:Gem::Version
|
314
|
+
hash: 3
|
315
|
+
segments:
|
316
|
+
- 0
|
317
|
+
version: "0"
|
318
|
+
type: :runtime
|
319
|
+
version_requirements: *id018
|
292
320
|
description:
|
293
321
|
email: support@vmware.com
|
294
322
|
executables:
|
@@ -355,6 +383,10 @@ files:
|
|
355
383
|
- vmc-ng/lib/vmc/plugin.rb
|
356
384
|
- vmc-ng/lib/vmc/version.rb
|
357
385
|
- vmc-ng/lib/vmc.rb
|
386
|
+
- vmc-ng/spec/app/apps_spec.rb
|
387
|
+
- vmc-ng/spec/helpers.rb
|
388
|
+
- vmc-ng/spec/Rakefile
|
389
|
+
- vmc-ng/spec/start/target_spec.rb
|
358
390
|
- vmc-ng/bin/vmc
|
359
391
|
- bin/vmc
|
360
392
|
homepage: http://vmware.com
|