MuranoCLI 3.2.0.beta.1 → 3.2.0.beta.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +4 -1
- data/.trustme.plugin +137 -0
- data/.trustme.sh +217 -117
- data/.trustme.vim +9 -3
- data/Gemfile +9 -3
- data/MuranoCLI.gemspec +8 -5
- data/Rakefile +1 -0
- data/dockers/Dockerfile.2.2.9 +6 -3
- data/dockers/Dockerfile.2.3.6 +6 -3
- data/dockers/Dockerfile.2.4.3 +6 -3
- data/dockers/Dockerfile.2.5.0 +6 -3
- data/dockers/Dockerfile.GemRelease +10 -8
- data/dockers/Dockerfile.m4 +23 -5
- data/dockers/docker-test.sh +65 -28
- data/docs/completions/murano_completion-bash +751 -57
- data/docs/develop.rst +10 -9
- data/lib/MrMurano/AccountBase.rb +95 -6
- data/lib/MrMurano/Commander-Entry.rb +9 -4
- data/lib/MrMurano/Config-Migrate.rb +2 -0
- data/lib/MrMurano/Config.rb +94 -26
- data/lib/MrMurano/Content.rb +1 -1
- data/lib/MrMurano/Exchange.rb +77 -42
- data/lib/MrMurano/Gateway.rb +1 -1
- data/lib/MrMurano/HttpAuthed.rb +20 -7
- data/lib/MrMurano/Logs.rb +10 -1
- data/lib/MrMurano/ProjectFile.rb +1 -1
- data/lib/MrMurano/ReCommander.rb +129 -73
- data/lib/MrMurano/Solution-ServiceConfig.rb +18 -11
- data/lib/MrMurano/Solution-Services.rb +78 -50
- data/lib/MrMurano/Solution-Users.rb +1 -1
- data/lib/MrMurano/Solution.rb +13 -63
- data/lib/MrMurano/SyncUpDown-Core.rb +185 -77
- data/lib/MrMurano/SyncUpDown-Item.rb +29 -4
- data/lib/MrMurano/SyncUpDown.rb +11 -11
- data/lib/MrMurano/Webservice-Cors.rb +1 -1
- data/lib/MrMurano/Webservice-Endpoint.rb +28 -17
- data/lib/MrMurano/Webservice-File.rb +103 -43
- data/lib/MrMurano/commands/domain.rb +1 -0
- data/lib/MrMurano/commands/element.rb +585 -0
- data/lib/MrMurano/commands/exchange.rb +211 -204
- data/lib/MrMurano/commands/gb.rb +1 -0
- data/lib/MrMurano/commands/globals.rb +17 -7
- data/lib/MrMurano/commands/init.rb +115 -101
- data/lib/MrMurano/commands/keystore.rb +1 -1
- data/lib/MrMurano/commands/logs.rb +2 -1
- data/lib/MrMurano/commands/postgresql.rb +17 -7
- data/lib/MrMurano/commands/service.rb +572 -0
- data/lib/MrMurano/commands/show.rb +7 -3
- data/lib/MrMurano/commands/solution.rb +2 -1
- data/lib/MrMurano/commands/solution_picker.rb +31 -15
- data/lib/MrMurano/commands/status.rb +205 -169
- data/lib/MrMurano/commands/sync.rb +70 -38
- data/lib/MrMurano/commands/token.rb +59 -14
- data/lib/MrMurano/commands/usage.rb +1 -0
- data/lib/MrMurano/commands.rb +2 -0
- data/lib/MrMurano/hash.rb +91 -0
- data/lib/MrMurano/http.rb +55 -6
- data/lib/MrMurano/makePretty.rb +47 -0
- data/lib/MrMurano/optparse.rb +60 -45
- data/lib/MrMurano/variegated/TruthyFalsey.rb +48 -0
- data/lib/MrMurano/variegated/ruby_dig.rb +64 -0
- data/lib/MrMurano/verbosing.rb +113 -3
- data/lib/MrMurano/version.rb +1 -1
- data/spec/Account_spec.rb +34 -20
- data/spec/Business_spec.rb +12 -9
- data/spec/Config_spec.rb +7 -1
- data/spec/Content_spec.rb +17 -1
- data/spec/GatewayBase_spec.rb +5 -2
- data/spec/GatewayDevice_spec.rb +4 -2
- data/spec/GatewayResource_spec.rb +4 -1
- data/spec/GatewaySettings_spec.rb +4 -1
- data/spec/HttpAuthed_spec.rb +73 -0
- data/spec/Http_spec.rb +32 -35
- data/spec/ProjectFile_spec.rb +1 -1
- data/spec/Solution-ServiceConfig_spec.rb +4 -1
- data/spec/Solution-ServiceEventHandler_spec.rb +6 -3
- data/spec/Solution-ServiceModules_spec.rb +4 -1
- data/spec/Solution-UsersRoles_spec.rb +4 -1
- data/spec/Solution_spec.rb +4 -1
- data/spec/SyncUpDown_spec.rb +1 -1
- data/spec/Webservice-Cors_spec.rb +4 -1
- data/spec/Webservice-Endpoint_spec.rb +9 -6
- data/spec/Webservice-File_spec.rb +17 -4
- data/spec/Webservice-Setting_spec.rb +6 -2
- data/spec/_workspace.rb +2 -0
- data/spec/cmd_common.rb +42 -13
- data/spec/cmd_content_spec.rb +17 -7
- data/spec/cmd_device_spec.rb +1 -1
- data/spec/cmd_domain_spec.rb +2 -2
- data/spec/cmd_element_spec.rb +400 -0
- data/spec/cmd_exchange_spec.rb +2 -2
- data/spec/cmd_init_spec.rb +59 -25
- data/spec/cmd_keystore_spec.rb +6 -3
- data/spec/cmd_link_spec.rb +10 -5
- data/spec/cmd_logs_spec.rb +1 -1
- data/spec/cmd_setting_application_spec.rb +18 -15
- data/spec/cmd_setting_product_spec.rb +7 -7
- data/spec/cmd_status_spec.rb +27 -17
- data/spec/cmd_syncdown_application_spec.rb +30 -3
- data/spec/cmd_syncdown_both_spec.rb +72 -18
- data/spec/cmd_syncup_spec.rb +71 -5
- data/spec/cmd_token_spec.rb +2 -2
- data/spec/cmd_usage_spec.rb +2 -2
- data/spec/dry_run_formatter.rb +27 -0
- data/spec/fixtures/dumped_config +8 -0
- data/spec/fixtures/exchange_element/element-show.json +1 -0
- data/spec/fixtures/exchange_element/swagger-mur-6407__10k.yaml +282 -0
- data/spec/fixtures/exchange_element/swagger-mur-6407__20k.yaml +588 -0
- data/spec/variegated_TruthyFalsey_spec.rb +29 -0
- metadata +51 -25
data/spec/cmd_common.rb
CHANGED
@@ -16,6 +16,7 @@ require 'tmpdir'
|
|
16
16
|
require 'webmock/rspec'
|
17
17
|
|
18
18
|
require 'MrMurano/Config'
|
19
|
+
require 'MrMurano/HttpAuthed'
|
19
20
|
|
20
21
|
# Prevent Commander from registering its at_exit hook.
|
21
22
|
# - Also print warning if spec exits, which rspec doesn't see as wrong.
|
@@ -50,6 +51,9 @@ at_exit do
|
|
50
51
|
warn('¡Unexpected spec exit killed rspec!')
|
51
52
|
warn('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
|
52
53
|
# DEVs: If you see this message, the last test exited unexpectedly.
|
54
|
+
warn('')
|
55
|
+
warn("Died on: #{$exited_abnormally}")
|
56
|
+
warn('')
|
53
57
|
end
|
54
58
|
end
|
55
59
|
alias original_at_exit at_exit unless defined?(original_at_exit)
|
@@ -96,6 +100,8 @@ RSpec.shared_context 'CI_CMD' do
|
|
96
100
|
args.push '-c', 'fullerror'
|
97
101
|
# The spinner output would make it hard to write expects().
|
98
102
|
args.push '--no-progress'
|
103
|
+
# Save the token.
|
104
|
+
args.push '--cache'
|
99
105
|
|
100
106
|
if Gem.win_platform?
|
101
107
|
cmd = args.map do |i|
|
@@ -159,7 +165,7 @@ RSpec.shared_context 'CI_CMD' do
|
|
159
165
|
expect(out).to \
|
160
166
|
eq('').or \
|
161
167
|
eq("No solutions found\n").or \
|
162
|
-
match(/^Deleted [\d]+ solutions
|
168
|
+
match(/^Deleted [\d]+ solutions?/)
|
163
169
|
expect(strip_color(err)).to eq('').or eq("No solutions found\n")
|
164
170
|
expect(status.exitstatus).to eq(0).or eq(1)
|
165
171
|
end
|
@@ -221,7 +227,7 @@ RSpec.shared_context 'CI_CMD' do
|
|
221
227
|
# Utility fcns: Strings.
|
222
228
|
|
223
229
|
# rname makes a random Murano-acceptable Solution name.
|
224
|
-
def rname(name)
|
230
|
+
def rname(name='')
|
225
231
|
#"#{name}-#{Random.new.rand.hash.abs.to_s(16)}"
|
226
232
|
# MUR-2454: Product name may only contain letters and numbers.
|
227
233
|
#"#{name}#{Random.new.rand.hash.abs.to_s(16)}"
|
@@ -272,7 +278,7 @@ RSpec.shared_context 'CI_CMD' do
|
|
272
278
|
|
273
279
|
def murano_command_runner(cmd, *args, wont_run: false, wont_parse: false)
|
274
280
|
# This is a functional test, so tell WebMock to back off.
|
275
|
-
|
281
|
+
allow_net_conn = WebMock::Config.instance.allow_net_connect != false
|
276
282
|
WebMock.allow_net_connect!
|
277
283
|
|
278
284
|
capture_stdio
|
@@ -288,25 +294,25 @@ RSpec.shared_context 'CI_CMD' do
|
|
288
294
|
$stdout = tmpout
|
289
295
|
$stderr = tmperr
|
290
296
|
|
291
|
-
$exited_abnormally =
|
297
|
+
$exited_abnormally = "#{cmd} #{args.join(' ')}"
|
298
|
+
|
299
|
+
MrMurano::HttpAuthed.instance.credentials_reset
|
292
300
|
|
293
301
|
# When Commander is loaded, it sets an at_exit hook, which we monkey
|
294
302
|
# patch in ReCommander. Since Config.validate_cmd is called before
|
295
303
|
# at_exit, it uses runner.command_exit to tell ReCommander's at_exit
|
296
304
|
# monkey patch not to call Commander.run!. Via rspec, we don't use the
|
297
305
|
# at_exit hook, or ReCommander.
|
298
|
-
|
299
|
-
|
300
|
-
$cfg.load
|
301
|
-
end
|
306
|
+
$cfg = MrMurano::Config.new(::Commander::Runner.instance)
|
307
|
+
$cfg.load
|
302
308
|
$cfg['tool.no-progress'] = true
|
303
|
-
$cfg.validate_cmd
|
309
|
+
$cfg.validate_cmd
|
304
310
|
runner = ::Commander::Runner.instance
|
305
311
|
unless defined?(runner.command_exit) && runner.command_exit
|
306
|
-
# Commander's at_exit hook calls runner.run! which runs the
|
307
|
-
# that was determined with Commander was loaded. I
|
308
|
-
# different ways to reset Runner.instance, but nothing worked;
|
309
|
-
# best bet is to just call the command directly.
|
312
|
+
# (lb): Commander's at_exit hook calls runner.run! which runs the
|
313
|
+
# command that was determined with Commander was loaded. I tried a
|
314
|
+
# few different ways to reset Runner.instance, but nothing worked;
|
315
|
+
# our best bet is to just call the command directly.
|
310
316
|
the_cmd = command(cmd.to_sym)
|
311
317
|
when_called = the_cmd.peek_when_called.dup
|
312
318
|
|
@@ -342,6 +348,8 @@ RSpec.shared_context 'CI_CMD' do
|
|
342
348
|
# $stdout, $stderr = STDOUT, STDERR
|
343
349
|
restore_stdio
|
344
350
|
|
351
|
+
WebMock.disable_net_connect! unless allow_net_conn
|
352
|
+
|
345
353
|
[strip_color(tmpout.string), strip_color(tmperr.string)]
|
346
354
|
end
|
347
355
|
|
@@ -376,11 +384,29 @@ RSpec.shared_context 'CI_CMD' do
|
|
376
384
|
require 'byebug/settings/histfile'
|
377
385
|
_ignored = ::Byebug::HistfileSetting::DEFAULT
|
378
386
|
|
387
|
+
$exited_abnormally = ex.example.to_s
|
388
|
+
|
379
389
|
@testdir = Pathname.new(Dir.pwd).realpath
|
380
390
|
Dir.mktmpdir do |hdir|
|
391
|
+
saved_home = Dir.home
|
381
392
|
ENV['HOME'] = hdir
|
382
393
|
Dir.chdir(hdir) do
|
383
394
|
Dir.mkdir('.murano')
|
395
|
+
|
396
|
+
Dir.chdir('.murano') do
|
397
|
+
begin
|
398
|
+
FileUtils.ln_s(File.join(saved_home, '.murano', 'tokens'), 'tokens')
|
399
|
+
rescue NotImplementedError => err
|
400
|
+
require 'rbconfig'
|
401
|
+
unless OS.windows?
|
402
|
+
warn(
|
403
|
+
'Unexpected: ln_s failed on non-Windows machine / ' \
|
404
|
+
"host_os: #{RbConfig::CONFIG['host_os']} / err: #{err}"
|
405
|
+
)
|
406
|
+
end
|
407
|
+
end
|
408
|
+
end
|
409
|
+
|
384
410
|
@tmpdir = File.join(hdir, 'project')
|
385
411
|
Dir.mkdir(@tmpdir)
|
386
412
|
Dir.chdir(@tmpdir) do
|
@@ -392,7 +418,10 @@ RSpec.shared_context 'CI_CMD' do
|
|
392
418
|
rm_symlink
|
393
419
|
end
|
394
420
|
end
|
421
|
+
ENV['HOME'] = saved_home
|
395
422
|
end
|
423
|
+
|
424
|
+
$exited_abnormally = false
|
396
425
|
end
|
397
426
|
end
|
398
427
|
|
data/spec/cmd_content_spec.rb
CHANGED
@@ -15,19 +15,24 @@ RSpec.describe 'murano content', :cmd, :needs_password do
|
|
15
15
|
|
16
16
|
before(:example) do
|
17
17
|
@product_name = rname('contestTest')
|
18
|
-
out, err, status = Open3.capture3(
|
18
|
+
out, err, status = Open3.capture3(
|
19
|
+
capcmd('murano', 'product', 'create', @product_name, '--save')
|
20
|
+
)
|
19
21
|
expect(err).to eq('')
|
20
22
|
expect(out.chomp).to match(/^[a-zA-Z0-9]+$/)
|
21
23
|
expect(status.exitstatus).to eq(0)
|
22
24
|
end
|
25
|
+
|
23
26
|
after(:example) do
|
24
|
-
out, err, status = Open3.capture3(
|
27
|
+
out, err, status = Open3.capture3(
|
28
|
+
capcmd('murano', 'solution', 'delete', '--yes', @product_name)
|
29
|
+
)
|
25
30
|
expect(out).to eq('')
|
26
31
|
expect(err).to eq('')
|
27
32
|
expect(status.exitstatus).to eq(0)
|
28
33
|
end
|
29
34
|
|
30
|
-
it 'life cycle' do
|
35
|
+
it 'life cycle', :club_10s do
|
31
36
|
out, err, status = Open3.capture3(capcmd('murano', 'content', 'list'))
|
32
37
|
#expect(out.lines).to match(
|
33
38
|
# [
|
@@ -43,7 +48,9 @@ RSpec.describe 'murano content', :cmd, :needs_password do
|
|
43
48
|
expect(status.exitstatus).to eq(0)
|
44
49
|
|
45
50
|
FileUtils.copy(File.join(@testdir, 'spec/fixtures/dumped_config'), 'myFile')
|
46
|
-
out, err, status = Open3.capture3(
|
51
|
+
out, err, status = Open3.capture3(
|
52
|
+
capcmd('murano', 'content', 'upload', 'myFile', '--tags', 'random=junk')
|
53
|
+
)
|
47
54
|
expect(out).to eq('')
|
48
55
|
expect(err).to eq('')
|
49
56
|
expect(status.exitstatus).to eq(0)
|
@@ -75,7 +82,9 @@ RSpec.describe 'murano content', :cmd, :needs_password do
|
|
75
82
|
)
|
76
83
|
expect(status.exitstatus).to eq(0)
|
77
84
|
|
78
|
-
out, err, status = Open3.capture3(
|
85
|
+
out, err, status = Open3.capture3(
|
86
|
+
capcmd('murano', 'content', 'download', 'myFile', '-o', 'testDown')
|
87
|
+
)
|
79
88
|
expect(out).to eq('')
|
80
89
|
expect(err).to eq('')
|
81
90
|
expect(status.exitstatus).to eq(0)
|
@@ -84,7 +93,9 @@ RSpec.describe 'murano content', :cmd, :needs_password do
|
|
84
93
|
tdf = IO.read('testDown')
|
85
94
|
expect(tdf).to eq(dcf)
|
86
95
|
|
87
|
-
out, err, status = Open3.capture3(
|
96
|
+
out, err, status = Open3.capture3(
|
97
|
+
capcmd('murano', 'content', 'delete', 'myFile', '-y')
|
98
|
+
)
|
88
99
|
expect(out).to eq('')
|
89
100
|
expect(err).to eq('')
|
90
101
|
expect(status.exitstatus).to eq(0)
|
@@ -105,4 +116,3 @@ RSpec.describe 'murano content', :cmd, :needs_password do
|
|
105
116
|
end
|
106
117
|
end
|
107
118
|
|
108
|
-
# vim: set ai et sw=2 ts=2 :
|
data/spec/cmd_device_spec.rb
CHANGED
@@ -84,7 +84,7 @@ RSpec.describe 'murano device', :cmd, :needs_password do
|
|
84
84
|
expect(status.exitstatus).to eq(0)
|
85
85
|
end
|
86
86
|
|
87
|
-
it 'writes and reads' do
|
87
|
+
it 'writes and reads', :club_10s do
|
88
88
|
FileUtils.mkpath('specs')
|
89
89
|
FileUtils.copy(
|
90
90
|
File.join(@testdir, 'spec/fixtures/product_spec_files/lightbulb.yaml'),
|
data/spec/cmd_domain_spec.rb
CHANGED
@@ -35,7 +35,7 @@ RSpec.describe 'murano domain', :cmd, :needs_password do
|
|
35
35
|
expect(status.exitstatus).to eq(0)
|
36
36
|
end
|
37
37
|
|
38
|
-
it 'show domain' do
|
38
|
+
it 'show domain', :club_20s, :club_10s do
|
39
39
|
out, err, status = Open3.capture3(capcmd('murano', 'domain'))
|
40
40
|
# 2017-05-31: Previously, the project could be named whatever and
|
41
41
|
# the URI would start with the same.
|
@@ -46,7 +46,7 @@ RSpec.describe 'murano domain', :cmd, :needs_password do
|
|
46
46
|
#expect(out.chomp).to end_with('m2.exosite.io')
|
47
47
|
out.lines.each do |line|
|
48
48
|
expect(line).to match(
|
49
|
-
%r{^(Product|Application): domain[Tt]est[a-z0-9]+ <[a-z0-9]+> https://[
|
49
|
+
%r{^(Product|Application): domain[Tt]est[a-z0-9]+ <[a-z0-9]+> https://[.\-a-z0-9]+$}
|
50
50
|
)
|
51
51
|
end
|
52
52
|
expect(err).to eq('')
|
@@ -0,0 +1,400 @@
|
|
1
|
+
# Copyright © 2016-2017 Exosite LLC. All Rights Reserved
|
2
|
+
# License: PROPRIETARY. See LICENSE.txt.
|
3
|
+
# frozen_string_literal: true
|
4
|
+
|
5
|
+
# vim:tw=0:ts=2:sw=2:et:ai
|
6
|
+
# Unauthorized copying of this file is strictly prohibited.
|
7
|
+
|
8
|
+
# (lb): 2018-05-01: Whoa. Coverage at 303 of 306 lines! 99.02%!!
|
9
|
+
|
10
|
+
require 'fileutils'
|
11
|
+
require 'json'
|
12
|
+
require 'open3'
|
13
|
+
require 'pathname'
|
14
|
+
require 'tty-editor'
|
15
|
+
require 'yaml'
|
16
|
+
|
17
|
+
require 'cmd_common'
|
18
|
+
require 'MrMurano/Config'
|
19
|
+
|
20
|
+
RSpec.describe 'murano element', :cmd, :needs_password do
|
21
|
+
include_context 'CI_CMD'
|
22
|
+
|
23
|
+
context 'without project' do
|
24
|
+
it 'usage' do
|
25
|
+
cmd_verify_help('element')
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def expect_exchange_element_table(stdout, stderr, num_cols: nil)
|
30
|
+
expect(stderr).to eq('')
|
31
|
+
lines = stdout.lines
|
32
|
+
# FIXME/2018-04-30: Is this too much detail??
|
33
|
+
# What about running test once, dumping output to file,
|
34
|
+
# and expecting same output next time?
|
35
|
+
# Outline of table. n columns. '+-----+-----+---...----+\n'
|
36
|
+
expect(lines[0]).to match(/^(\+-+){#{num_cols}}\+$/)
|
37
|
+
# Header. "... key | value ..."
|
38
|
+
expect(lines[1]).to match(/^\| key \+| value \+|$/)
|
39
|
+
# Separator.
|
40
|
+
expect(lines[2]).to match(/^(\+-+){#{num_cols}}\+$/)
|
41
|
+
# Content. Starts with nested.hash.key.
|
42
|
+
(3..(lines.length - 2)).to_a.each do |line|
|
43
|
+
expect(lines[line]).to match(/^\| [\.0-9a-zA-Z]* +\| /)
|
44
|
+
end
|
45
|
+
expect(lines[-1]).to match(/^(\+-+){#{num_cols}}\+$/)
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'show' do
|
49
|
+
it '--help' do
|
50
|
+
stdout, stderr = murano_command_wont_parse('element show', '--help')
|
51
|
+
expect(stdout).to a_string_starting_with('Usage:')
|
52
|
+
expect(stderr).to eq('')
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'using ambiguous name' do
|
56
|
+
# MEH/2018-04-30: This test is dependent on the platform having
|
57
|
+
# more than one element with the term 'IoT' in its name!
|
58
|
+
# 59bc24836b12c505c98c5a51: ‘Twilio SMS Service’
|
59
|
+
# 5adedb7cdcd2dd1d04082fba: ‘Public application for the twilio’
|
60
|
+
#
|
61
|
+
# FIXME/2018-04-30: Make test-specific elements for this test!
|
62
|
+
stdout, stderr = murano_command_exits('element show', 'twilio')
|
63
|
+
expect(stdout).to eq('')
|
64
|
+
expect(stderr).to a_string_starting_with(
|
65
|
+
'Please be more specific: More than one matching element was found:'
|
66
|
+
)
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'as default-table' do
|
70
|
+
# FIXME/2018-04-30: Make test-specific elements for this test!
|
71
|
+
stdout, stderr = murano_command_run('element show', 'MUR-6407')
|
72
|
+
expect_exchange_element_table(stdout, stderr, num_cols: 2)
|
73
|
+
expect(stderr).to eq('')
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'as table wrap' do
|
77
|
+
# FIXME/2018-04-30: Make test-specific elements for this test!
|
78
|
+
stdout, stderr = murano_command_run('element show', 'MUR-6407', '--wrap')
|
79
|
+
expect_exchange_element_table(stdout, stderr, num_cols: 2)
|
80
|
+
expect(stderr).to eq('')
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'as table truncate' do
|
84
|
+
# FIXME/2018-04-30: Make test-specific elements for this test!
|
85
|
+
stdout, stderr = murano_command_run('element show', 'MUR-6407', '--truncate')
|
86
|
+
expect_exchange_element_table(stdout, stderr, num_cols: 2)
|
87
|
+
expect(stderr).to eq('')
|
88
|
+
end
|
89
|
+
|
90
|
+
# (lb): NOTE: This does not add any additional coverage to element.rb:
|
91
|
+
it 'as json' do
|
92
|
+
# FIXME/2018-04-30: Make test-specific elements for this test!
|
93
|
+
stdout, stderr = murano_command_run('element show', '--json', 'MUR-6407')
|
94
|
+
expect { JSON.parse(stdout) }.to_not raise_error
|
95
|
+
expect(stderr).to eq('')
|
96
|
+
end
|
97
|
+
|
98
|
+
# (lb): NOTE: This does not add any additional coverage to element.rb:
|
99
|
+
it 'as yaml' do
|
100
|
+
# FIXME/2018-04-30: Make test-specific elements for this test!
|
101
|
+
stdout, stderr = murano_command_run('element show', 'MUR-6407', '--yaml')
|
102
|
+
expect { YAML.parse(stdout) }.to_not raise_error
|
103
|
+
expect(stderr).to eq('')
|
104
|
+
end
|
105
|
+
|
106
|
+
# (lb): This adds 1 line of coverage.
|
107
|
+
it 'as csv' do
|
108
|
+
# FIXME/2018-04-30: Make test-specific elements for this test!
|
109
|
+
stdout, stderr = murano_command_run('element show', 'MUR-6407', '--csv')
|
110
|
+
expect(stdout).to_not eq('')
|
111
|
+
expect(stderr).to eq('')
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
context 'edit' do
|
116
|
+
before(:example) do
|
117
|
+
@json_input_file = 'element-show.json'
|
118
|
+
@spec_swagger_20k = 'swagger-mur-6407__20k.yaml'
|
119
|
+
@spec_swagger_10k = 'swagger-mur-6407__10k.yaml'
|
120
|
+
[
|
121
|
+
@json_input_file,
|
122
|
+
@spec_swagger_20k,
|
123
|
+
@spec_swagger_10k,
|
124
|
+
].each do |path|
|
125
|
+
FileUtils.copy(
|
126
|
+
File.join(@testdir, "spec/fixtures/exchange_element/#{path}"), path
|
127
|
+
)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def element_editor_expect_edit_json_full
|
132
|
+
# Mock the $EDITOR session.
|
133
|
+
expect(TTY::Editor).to receive(:open) do |path|
|
134
|
+
edit_json_make_unique_contact(path)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def edit_json_make_unique_contact(path)
|
139
|
+
pname = path.is_a?(Pathname) && path || Pathname.new(path)
|
140
|
+
pname.write pname.read.gsub(
|
141
|
+
/\n "contact": "[a-f0-9]+",\n/,
|
142
|
+
%(\n "contact": "#{rname}",\n)
|
143
|
+
)
|
144
|
+
end
|
145
|
+
|
146
|
+
def edit_specs_yaml_make_unique_contact(path)
|
147
|
+
pname = path.is_a?(Pathname) && path || Pathname.new(path)
|
148
|
+
rname7 = rname[0..6]
|
149
|
+
pname.write pname.read.gsub(
|
150
|
+
/\n name: Exosite Exosite Exosite Exosite\n/,
|
151
|
+
%(\n name: #{rname7} #{rname7} #{rname7} #{rname7}\n)
|
152
|
+
)
|
153
|
+
end
|
154
|
+
|
155
|
+
def element_editor_expect_edit_plain_contact
|
156
|
+
# Mock the $EDITOR session.
|
157
|
+
expect(TTY::Editor).to receive(:open) do |path|
|
158
|
+
pname = path.is_a?(Pathname) && path || Pathname.new(path)
|
159
|
+
pname.write(rname)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
# DEL:
|
164
|
+
def element_editor_expect_edit_json_from_string
|
165
|
+
expect(TTY::Editor).to receive(:open) do |path|
|
166
|
+
pname = path.is_a?(Pathname) && path || Pathname.new(path)
|
167
|
+
pname.write(
|
168
|
+
%({"tiers":[],"bizid":"55cop31gs89","access":"private","attachment":{},"contact":"#{rname}","description":"For testing Murano CLI element-edit.\\n\\nTEST2222\\n\\nTEST MORE","image":{"detail":{"color":"#224123","filename":"","url":""},"thumbnail":{"color":"#224655","filename":"xxx","url":""}},"markdown":"AxxxxAA2333BBBCCC\\n","name":"MUR-6407 Test Element","source":{"from":"service","name":"mur6407testelement","url":"https://testtesttest.apps.exosite-dev.io/swagger-mur-6407.yaml"},"specs":"","type":"service","tags":[],"active":true,"approval":"approved","elementId":"5ae3600e313d01708c2a6e0f"})
|
169
|
+
)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
it '--help' do
|
174
|
+
stdout, stderr = murano_command_wont_parse('element edit', '--help')
|
175
|
+
expect(stdout).to a_string_starting_with('Usage:')
|
176
|
+
expect(stderr).to eq('')
|
177
|
+
end
|
178
|
+
|
179
|
+
it 'as static field option' do
|
180
|
+
stdout, stderr = murano_command_run(
|
181
|
+
'element edit', '--contact', rname, 'MUR-6407'
|
182
|
+
)
|
183
|
+
expect(stdout).to eq('')
|
184
|
+
expect(stderr).to eq('')
|
185
|
+
end
|
186
|
+
|
187
|
+
it 'as dynamic field option' do
|
188
|
+
stdout, stderr = murano_command_run(
|
189
|
+
'element edit', '-e', "contact=#{rname}", 'MUR-6407'
|
190
|
+
)
|
191
|
+
expect(stdout).to eq('')
|
192
|
+
expect(stderr).to eq('')
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'as dynamic edit empty string without update' do
|
196
|
+
# I.e., @edit_fields[''] = nil, meaning should bring up editor.
|
197
|
+
# FIXME: Requires (lb)'s fixed commander library.
|
198
|
+
|
199
|
+
# If we don't change the file, Murano CLI will not PUT to BizAPI.
|
200
|
+
expect(TTY::Editor).to receive(:open).once
|
201
|
+
stdout, stderr = murano_command_exits(
|
202
|
+
'element edit', '-e', '', 'MUR-6407'
|
203
|
+
)
|
204
|
+
expect(stdout).to eq('')
|
205
|
+
expect(stderr).to eq("No new field values specified to update.\n")
|
206
|
+
end
|
207
|
+
|
208
|
+
it 'as dynamic edit empty string with update' do
|
209
|
+
element_editor_expect_edit_json_full
|
210
|
+
stdout, stderr = murano_command_run(
|
211
|
+
'element edit', '-e', '', 'MUR-6407'
|
212
|
+
)
|
213
|
+
expect(stdout).to eq('')
|
214
|
+
expect(stderr).to eq('')
|
215
|
+
end
|
216
|
+
|
217
|
+
it 'as dynamic edit no field with update' do
|
218
|
+
element_editor_expect_edit_json_full
|
219
|
+
stdout, stderr = murano_command_run(
|
220
|
+
'element edit', '-e', '--', 'MUR-6407'
|
221
|
+
)
|
222
|
+
expect(stdout).to eq('')
|
223
|
+
expect(stderr).to eq('')
|
224
|
+
end
|
225
|
+
|
226
|
+
it 'as dynamic edit set empty string' do
|
227
|
+
# I.e., @edit_fields[''] = ''
|
228
|
+
stdout, stderr = murano_command_run(
|
229
|
+
#'element edit', '-e', "''=", 'MUR-6407'
|
230
|
+
'element edit', '-e', '=', 'MUR-6407'
|
231
|
+
)
|
232
|
+
expect(stdout).to eq('')
|
233
|
+
expect(stderr).to eq(
|
234
|
+
%(Request Failed: 400: [400] child "type" fails because ["type" is required]\n)
|
235
|
+
)
|
236
|
+
end
|
237
|
+
|
238
|
+
it 'as edit with too many fields specified' do
|
239
|
+
stdout, stderr = murano_command_exits(
|
240
|
+
'element edit', '-e', "contact=#{rname}", '-e', 'markdown', 'MUR-6407'
|
241
|
+
)
|
242
|
+
expect(stdout).to eq('')
|
243
|
+
expect(stderr).to eq(
|
244
|
+
%(Please specify at most one field when not specifing all field values.\n)
|
245
|
+
)
|
246
|
+
end
|
247
|
+
|
248
|
+
it 'as edit with no action specified' do
|
249
|
+
stdout, stderr = murano_command_exits(
|
250
|
+
'element edit', 'MUR-6407'
|
251
|
+
)
|
252
|
+
expect(stdout).to eq('')
|
253
|
+
expect(stderr).to eq(
|
254
|
+
%(Please specify one or more -e/--edit options, or an input file.\n)
|
255
|
+
)
|
256
|
+
end
|
257
|
+
|
258
|
+
it 'as edit with input file not found' do
|
259
|
+
bad_path = "/path/to/nowhere/#{rname}.json"
|
260
|
+
stdout, stderr = murano_command_exits(
|
261
|
+
'element edit', 'MUR-6407', bad_path
|
262
|
+
)
|
263
|
+
expect(stdout).to eq('')
|
264
|
+
expect(stderr).to eq(
|
265
|
+
%(Input file not found: #{bad_path}\n)
|
266
|
+
)
|
267
|
+
end
|
268
|
+
|
269
|
+
it 'as edit with input file found and valid' do
|
270
|
+
path = Pathname.new(@json_input_file)
|
271
|
+
path.write path.read.gsub(
|
272
|
+
/,"contact":"[a-f0-9]+",/,
|
273
|
+
%(,"contact":"#{rname}",)
|
274
|
+
)
|
275
|
+
stdout, stderr = murano_command_run(
|
276
|
+
'element edit', 'MUR-6407', @json_input_file
|
277
|
+
)
|
278
|
+
expect(stdout).to eq('')
|
279
|
+
expect(stderr).to eq('')
|
280
|
+
end
|
281
|
+
|
282
|
+
it 'as edit with input file and too many fields specified' do
|
283
|
+
stdout, stderr = murano_command_exits(
|
284
|
+
'element edit', '-e', 'contact', '-e', 'markdown', 'MUR-6407', @spec_swagger_20k
|
285
|
+
)
|
286
|
+
expect(stdout).to eq('')
|
287
|
+
expect(stderr).to eq(
|
288
|
+
%(Please specify at most a single field when specifing an input file.\n)
|
289
|
+
)
|
290
|
+
end
|
291
|
+
|
292
|
+
it 'as edit with input file and value specified' do
|
293
|
+
stdout, stderr = murano_command_exits(
|
294
|
+
'element edit', '-e', 'contact=XYZ', 'MUR-6407', @spec_swagger_20k
|
295
|
+
)
|
296
|
+
expect(stdout).to eq('')
|
297
|
+
expect(stderr).to eq(
|
298
|
+
%(Please do not specify a value when specifing an input file.\n)
|
299
|
+
)
|
300
|
+
end
|
301
|
+
|
302
|
+
it 'as edit with input file that is too large and unrecognized field' do
|
303
|
+
stdout, stderr = murano_command_run(
|
304
|
+
'element edit', '--edit', "spec=@#{@spec_swagger_20k}", 'MUR-6407'
|
305
|
+
)
|
306
|
+
expect(stdout).to eq('')
|
307
|
+
expect(stderr).to eq(
|
308
|
+
%(Request Failed: 400: [400] "spec" is not allowed\n)
|
309
|
+
)
|
310
|
+
end
|
311
|
+
|
312
|
+
it 'as edit with input file that should not be parsed' do
|
313
|
+
stdout, stderr = murano_command_run(
|
314
|
+
'element edit', '--edit', "specs=@#{@spec_swagger_20k}", 'MUR-6407'
|
315
|
+
)
|
316
|
+
expect(stdout).to eq('')
|
317
|
+
expect(stderr).to eq(
|
318
|
+
%(Request Failed: 400: [400] child "specs" fails because ["specs" must be a string]\n)
|
319
|
+
)
|
320
|
+
end
|
321
|
+
|
322
|
+
# FIXME/2018-05-01 00:10: How does Tilstra circumvent 20k limit?
|
323
|
+
it 'as edit with input file that is too large' do
|
324
|
+
stdout, stderr = murano_command_run(
|
325
|
+
'element edit', '--edit', 'specs', '--plain', '--', 'MUR-6407', @spec_swagger_20k
|
326
|
+
)
|
327
|
+
expect(stdout).to eq('')
|
328
|
+
expect(stderr).to eq(
|
329
|
+
%(Request Failed: 400: [400] child "specs" fails because ["specs" length must be less than or equal to 10000 characters long]\n)
|
330
|
+
)
|
331
|
+
end
|
332
|
+
|
333
|
+
it 'as edit with input file that is just right' do
|
334
|
+
edit_specs_yaml_make_unique_contact(@spec_swagger_10k)
|
335
|
+
stdout, stderr = murano_command_run(
|
336
|
+
'element edit', '--edit', 'specs', '--plain', '--', 'MUR-6407', @spec_swagger_10k
|
337
|
+
)
|
338
|
+
expect(stdout).to eq('')
|
339
|
+
expect(stderr).to eq('')
|
340
|
+
|
341
|
+
# Send same file again.
|
342
|
+
stdout, stderr = murano_command_exits(
|
343
|
+
'element edit', '--edit', 'specs', '--plain', '--', 'MUR-6407', @spec_swagger_10k
|
344
|
+
)
|
345
|
+
expect(stdout).to eq('')
|
346
|
+
expect(stderr).to eq("No new field values specified to update.\n")
|
347
|
+
end
|
348
|
+
|
349
|
+
it 'as dynamic edit single field no value uses EDITOR' do
|
350
|
+
element_editor_expect_edit_plain_contact
|
351
|
+
stdout, stderr = murano_command_run(
|
352
|
+
'element edit', '-e', 'contact', '--', 'MUR-6407'
|
353
|
+
)
|
354
|
+
expect(stdout).to eq('')
|
355
|
+
expect(stderr).to eq('')
|
356
|
+
end
|
357
|
+
|
358
|
+
it 'as dynamic edit nested field change value' do
|
359
|
+
stdout, stderr = murano_command_run(
|
360
|
+
'element edit', '-e', "image.detail.color=0x#{rname[0..5]}", 'MUR-6407'
|
361
|
+
)
|
362
|
+
expect(stdout).to eq('')
|
363
|
+
expect(stderr).to eq('')
|
364
|
+
end
|
365
|
+
|
366
|
+
# (lb): Get 2 more lines of coverage.
|
367
|
+
it 'as dynamic edit no field with update from string' do
|
368
|
+
stdout, stderr = murano_command_run(
|
369
|
+
'element edit',
|
370
|
+
'-e',
|
371
|
+
%(={"bizid":"55cop31gs89","access":"private","attachment":{},"contact":"#{rname}","description":"For testing Murano CLI element-edit.\\n\\nTEST2222\\n\\nTEST MORE","image":{"detail":{"color":"#224123","filename":"","url":""},"thumbnail":{"color":"#224655","filename":"xxx","url":""}},"markdown":"AxxxxAA2333BBBCCC\\n","name":"MUR-6407 Test Element","source":{"from":"service","name":"mur6407testelement","url":"https://testtesttest.apps.exosite-dev.io/swagger-mur-6407.yaml"},"specs":"","type":"service","tags":[],"active":true,"elementId":"5ae3600e313d01708c2a6e0f"}),
|
372
|
+
'MUR-6407'
|
373
|
+
)
|
374
|
+
expect(stdout).to eq('')
|
375
|
+
expect(stderr).to eq('')
|
376
|
+
end
|
377
|
+
|
378
|
+
# (lb): Get 2 more lines of coverage.
|
379
|
+
it 'as dynamic edit no field with update from string not valid Hash' do
|
380
|
+
stdout, stderr = murano_command_exits(
|
381
|
+
'element edit', '-e', %(={), 'MUR-6407'
|
382
|
+
)
|
383
|
+
expect(stdout).to eq('')
|
384
|
+
expect(stderr).to eq %(The document object is not a Hash: {\n765: unexpected token at '{'\n)
|
385
|
+
end
|
386
|
+
|
387
|
+
# (lb): No additional coverage, other than integration.
|
388
|
+
it 'as dynamic edit no field with update from string fields not allowed' do
|
389
|
+
stdout, stderr = murano_command_run(
|
390
|
+
'element edit',
|
391
|
+
'-e',
|
392
|
+
%(={"tiers":[],"bizid":"55cop31gs89","access":"private","attachment":{},"contact":"#{rname}","description":"For testing Murano CLI element-edit.\\n\\nTEST2222\\n\\nTEST MORE","image":{"detail":{"color":"#224123","filename":"","url":""},"thumbnail":{"color":"#224655","filename":"xxx","url":""}},"markdown":"AxxxxAA2333BBBCCC\\n","name":"MUR-6407 Test Element","source":{"from":"service","name":"mur6407testelement","url":"https://testtesttest.apps.exosite-dev.io/swagger-mur-6407.yaml"},"specs":"","type":"service","tags":[],"active":true,"approval":"approved","elementId":"5ae3600e313d01708c2a6e0f"}),
|
393
|
+
'MUR-6407'
|
394
|
+
)
|
395
|
+
expect(stdout).to eq('')
|
396
|
+
expect(stderr).to eq %(Request Failed: 400: [400] "tiers" is not allowed. "approval" is not allowed\n)
|
397
|
+
end
|
398
|
+
end
|
399
|
+
end
|
400
|
+
|
data/spec/cmd_exchange_spec.rb
CHANGED
@@ -39,7 +39,7 @@ RSpec.describe 'murano exchange', :cmd, :needs_password do
|
|
39
39
|
expect(lines[3]).to match(/^(\+-+){#{num_cols}}\+$/)
|
40
40
|
# Content. Starts with elementId.
|
41
41
|
(4..(lines.length - 2)).to_a.each do |line|
|
42
|
-
expect(lines[line]).to match(/^\| [0-9a-f]+
|
42
|
+
expect(lines[line]).to match(/^\| [0-9a-f]+ +\| /)
|
43
43
|
end
|
44
44
|
expect(lines[-1]).to match(/^(\+-+){#{num_cols}}\+$/)
|
45
45
|
end
|
@@ -51,7 +51,7 @@ RSpec.describe 'murano exchange', :cmd, :needs_password do
|
|
51
51
|
expect_exchange_element_table(stdout, stderr, num_cols: 4)
|
52
52
|
end
|
53
53
|
|
54
|
-
it 'only ids' do
|
54
|
+
it 'only ids', :club_20s, :club_10s do
|
55
55
|
stdout, stderr = murano_command_run('exchange list', '--idonly')
|
56
56
|
expect(stderr).to eq('')
|
57
57
|
stdout.lines.each do |line|
|