MuranoCLI 3.0.1 → 3.0.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.
- checksums.yaml +4 -4
- data/.agignore +1 -0
- data/.rubocop.yml +67 -5
- data/Gemfile +6 -3
- data/MuranoCLI.gemspec +14 -10
- data/README.markdown +299 -126
- data/Rakefile +6 -1
- data/bin/murano +2 -2
- data/docs/completions/murano_completion-bash +93 -0
- data/lib/MrMurano.rb +19 -2
- data/lib/MrMurano/Business.rb +22 -19
- data/lib/MrMurano/Config.rb +19 -9
- data/lib/MrMurano/Content.rb +4 -4
- data/lib/MrMurano/Exchange-Element.rb +99 -0
- data/lib/MrMurano/Exchange.rb +137 -0
- data/lib/MrMurano/Gateway.rb +9 -9
- data/lib/MrMurano/Keystore.rb +4 -2
- data/lib/MrMurano/ReCommander.rb +3 -5
- data/lib/MrMurano/Solution-ServiceConfig.rb +12 -12
- data/lib/MrMurano/Solution-Services.rb +15 -14
- data/lib/MrMurano/Solution-Users.rb +2 -2
- data/lib/MrMurano/Solution.rb +43 -49
- data/lib/MrMurano/SolutionId.rb +28 -28
- data/lib/MrMurano/SyncUpDown.rb +32 -22
- data/lib/MrMurano/Webservice-Endpoint.rb +2 -1
- data/lib/MrMurano/Webservice.rb +5 -5
- data/lib/MrMurano/commands.rb +2 -1
- data/lib/MrMurano/commands/business.rb +21 -19
- data/lib/MrMurano/commands/domain.rb +16 -2
- data/lib/MrMurano/commands/exchange.rb +272 -0
- data/lib/MrMurano/commands/globals.rb +17 -1
- data/lib/MrMurano/commands/init.rb +3 -3
- data/lib/MrMurano/commands/link.rb +16 -16
- data/lib/MrMurano/commands/postgresql.rb +2 -2
- data/lib/MrMurano/commands/show.rb +13 -7
- data/lib/MrMurano/commands/solution.rb +23 -17
- data/lib/MrMurano/commands/solution_picker.rb +49 -44
- data/lib/MrMurano/commands/sync.rb +2 -1
- data/lib/MrMurano/commands/timeseries.rb +2 -2
- data/lib/MrMurano/commands/tsdb.rb +2 -2
- data/lib/MrMurano/hash.rb +19 -7
- data/lib/MrMurano/http.rb +12 -2
- data/lib/MrMurano/orderedhash.rb +200 -0
- data/lib/MrMurano/spec_commander.rb +98 -0
- data/lib/MrMurano/verbosing.rb +2 -2
- data/lib/MrMurano/version.rb +2 -2
- data/spec/Business_spec.rb +8 -6
- data/spec/Solution-ServiceConfig_spec.rb +1 -1
- data/spec/SyncUpDown_spec.rb +6 -6
- data/spec/_workspace.rb +9 -4
- data/spec/cmd_business_spec.rb +8 -2
- data/spec/cmd_common.rb +266 -25
- data/spec/cmd_exchange_spec.rb +118 -0
- data/spec/cmd_help_spec.rb +54 -13
- data/spec/cmd_init_spec.rb +1 -12
- data/spec/cmd_link_spec.rb +94 -72
- data/spec/spec_helper.rb +11 -16
- metadata +23 -17
data/spec/Business_spec.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Last Modified: 2017.
|
1
|
+
# Last Modified: 2017.09.11 /coding: utf-8
|
2
2
|
|
3
3
|
# Copyright © 2016-2017 Exosite LLC.
|
4
4
|
# License: MIT. See LICENSE.txt.
|
@@ -37,6 +37,7 @@ RSpec.describe MrMurano::Business do
|
|
37
37
|
pid: "ABC",
|
38
38
|
modelId: "cde",
|
39
39
|
label: "fts",
|
40
|
+
api_id: "XYZ",
|
40
41
|
sid: "XYZ",
|
41
42
|
name: "XYZ",},
|
42
43
|
{bizid: "XYZxyz",
|
@@ -44,6 +45,7 @@ RSpec.describe MrMurano::Business do
|
|
44
45
|
pid: "fgh",
|
45
46
|
modelId: "ijk",
|
46
47
|
label: "lua-test",
|
48
|
+
api_id: "XYZ",
|
47
49
|
sid: "XYZ",
|
48
50
|
name: "XYZ",},
|
49
51
|
]
|
@@ -106,14 +108,14 @@ RSpec.describe MrMurano::Business do
|
|
106
108
|
{bizid: "XYZxyz",
|
107
109
|
type: "application",
|
108
110
|
domain: "XYZxyz.apps.exosite.io",
|
109
|
-
|
111
|
+
api_id: "ACBabc",
|
110
112
|
sid: "ACBabc",
|
111
113
|
name: "ijk",
|
112
114
|
},
|
113
115
|
{bizid: "XYZxyz",
|
114
116
|
type: "application",
|
115
117
|
domain: "XYZxyz.apps.exosite.io",
|
116
|
-
|
118
|
+
api_id: "DEFdef",
|
117
119
|
sid: "DEFdef",
|
118
120
|
name: "lmn",
|
119
121
|
},
|
@@ -183,7 +185,7 @@ RSpec.describe MrMurano::Business do
|
|
183
185
|
{bizid: "XYZxyz",
|
184
186
|
type: "product",
|
185
187
|
domain: "ABCabc.m2.exosite.io",
|
186
|
-
|
188
|
+
api_id: "ABCabc",
|
187
189
|
sid: "ABCabc",
|
188
190
|
name: "XXX",
|
189
191
|
},
|
@@ -192,7 +194,7 @@ RSpec.describe MrMurano::Business do
|
|
192
194
|
{bizid: "XYZxyz",
|
193
195
|
type: "application",
|
194
196
|
domain: "XYZxyz.apps.exosite.io",
|
195
|
-
|
197
|
+
api_id: "DEFdef",
|
196
198
|
sid: "DEFdef",
|
197
199
|
name: "XXX",
|
198
200
|
},
|
@@ -222,7 +224,7 @@ RSpec.describe MrMurano::Business do
|
|
222
224
|
|
223
225
|
sol = @biz.new_solution!("one", :product)
|
224
226
|
expect(sol.valid?).to be true
|
225
|
-
expect(sol.
|
227
|
+
expect(sol.api_id).to eq("abc123def456ghi78")
|
226
228
|
end
|
227
229
|
|
228
230
|
# if false
|
@@ -18,7 +18,7 @@ RSpec.describe MrMurano::ServiceConfig do
|
|
18
18
|
$cfg['product.id'] = 'XYZ'
|
19
19
|
$cfg['application.id'] = 'XYZ'
|
20
20
|
|
21
|
-
# ServiceConfig needs an
|
21
|
+
# ServiceConfig needs an api_id, else one could instantiate
|
22
22
|
# ServiceConfigApplication or ServiceConfigProduct.
|
23
23
|
@srv = MrMurano::ServiceConfig.new('XYZ')
|
24
24
|
allow(@srv).to receive(:token).and_return("TTTTTTTTTT")
|
data/spec/SyncUpDown_spec.rb
CHANGED
@@ -12,20 +12,20 @@ class TSUD
|
|
12
12
|
|
13
13
|
def initialize
|
14
14
|
# 2017-07-03: See MrMurano::SolutionBase.state for the list of attrs.
|
15
|
-
@
|
16
|
-
@
|
15
|
+
@api_id = 'XYZ'
|
16
|
+
@valid_api_id = true
|
17
17
|
@uriparts = []
|
18
18
|
@solntype = 'application.id'
|
19
19
|
@itemkey = :name
|
20
20
|
@project_section = :routes
|
21
21
|
end
|
22
22
|
|
23
|
-
def
|
24
|
-
@
|
23
|
+
def api_id
|
24
|
+
@api_id
|
25
25
|
end
|
26
26
|
|
27
|
-
def
|
28
|
-
@
|
27
|
+
def api_id?
|
28
|
+
@valid_api_id
|
29
29
|
end
|
30
30
|
|
31
31
|
def fetch(id)
|
data/spec/_workspace.rb
CHANGED
@@ -1,9 +1,15 @@
|
|
1
|
+
# Last Modified: 2017.08.29 /coding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Copyright © 2016-2017 Exosite LLC.
|
5
|
+
# License: MIT. See LICENSE.txt.
|
6
|
+
# vim:tw=0:ts=2:sw=2:et:ai
|
7
|
+
|
1
8
|
require 'fileutils'
|
2
9
|
require 'pathname'
|
3
10
|
require 'tmpdir'
|
4
11
|
|
5
|
-
RSpec.shared_context
|
6
|
-
|
12
|
+
RSpec.shared_context 'WORKSPACE' do
|
7
13
|
around(:example) do |ex|
|
8
14
|
@testdir = Pathname.new(Dir.pwd).realpath
|
9
15
|
Dir.mktmpdir do |hdir|
|
@@ -16,7 +22,7 @@ RSpec.shared_context "WORKSPACE" do
|
|
16
22
|
@project_dir = File.join(ENV['HOME'], 'work', 'project')
|
17
23
|
FileUtils.mkpath(@project_dir)
|
18
24
|
Dir.chdir(@project_dir) do
|
19
|
-
|
25
|
+
ex.run
|
20
26
|
end
|
21
27
|
end
|
22
28
|
ENV['HOME'] = saved_home
|
@@ -24,4 +30,3 @@ RSpec.shared_context "WORKSPACE" do
|
|
24
30
|
end
|
25
31
|
end
|
26
32
|
|
27
|
-
# vim: set ai et sw=2 ts=2 :
|
data/spec/cmd_business_spec.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Last Modified: 2017.08.
|
1
|
+
# Last Modified: 2017.08.31 /coding: utf-8
|
2
2
|
# frozen_string_literal: probably not yet
|
3
3
|
|
4
4
|
# Copyright © 2016-2017 Exosite LLC.
|
@@ -13,6 +13,12 @@ require 'cmd_common'
|
|
13
13
|
RSpec.describe 'murano business', :cmd, :needs_password do
|
14
14
|
include_context "CI_CMD"
|
15
15
|
|
16
|
+
context "without project" do
|
17
|
+
it "help" do
|
18
|
+
cmd_verify_help('business')
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
16
22
|
context "list" do
|
17
23
|
it "as table" do
|
18
24
|
out, err, status = Open3.capture3(capcmd('murano', 'business', 'list'))
|
@@ -28,7 +34,7 @@ RSpec.describe 'murano business', :cmd, :needs_password do
|
|
28
34
|
it "as json" do
|
29
35
|
out, err, status = Open3.capture3(capcmd('murano', 'business', 'list', '-c', 'outformat=json'))
|
30
36
|
expect(err).to eq("")
|
31
|
-
expect{JSON.parse(out)}.to_not raise_error
|
37
|
+
expect{ JSON.parse(out) }.to_not raise_error
|
32
38
|
expect(status.exitstatus).to eq(0)
|
33
39
|
end
|
34
40
|
|
data/spec/cmd_common.rb
CHANGED
@@ -1,17 +1,68 @@
|
|
1
|
+
# Last Modified: 2017.08.31 /coding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Copyright © 2016-2017 Exosite LLC.
|
5
|
+
# License: MIT. See LICENSE.txt.
|
6
|
+
# vim:tw=0:ts=2:sw=2:et:ai
|
7
|
+
|
8
|
+
require 'highline'
|
9
|
+
# Set HighLine's $terminal global.
|
10
|
+
require 'highline/import'
|
1
11
|
require 'pathname'
|
2
12
|
require 'shellwords'
|
3
13
|
require 'timeout'
|
4
14
|
require 'tmpdir'
|
15
|
+
require 'webmock/rspec'
|
16
|
+
|
5
17
|
require 'MrMurano/Config'
|
6
18
|
|
7
|
-
|
19
|
+
# Prevent Commander from registering its at_exit hook.
|
20
|
+
# - Also print warning if spec exits, which rspec doesn't see as wrong.
|
21
|
+
# - Note that this comes before importing Commander.
|
22
|
+
$exited_abnormally = false
|
23
|
+
at_exit do
|
24
|
+
if $exited_abnormally
|
25
|
+
STDERR.puts('¡!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
|
26
|
+
STDERR.puts('¡Unexpected spec exit killed rspec!')
|
27
|
+
STDERR.puts('¡!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
alias original_at_exit at_exit
|
31
|
+
def at_exit(*args, &block)
|
32
|
+
#original_at_exit *args, &block
|
33
|
+
# pass!
|
34
|
+
end
|
35
|
+
|
36
|
+
require 'MrMurano/spec_commander.rb'
|
37
|
+
|
38
|
+
module Commander
|
39
|
+
class Command
|
40
|
+
attr_writer :when_called
|
41
|
+
#def when_called=(args)
|
42
|
+
# @when_called = args
|
43
|
+
#end
|
44
|
+
|
45
|
+
def peek_when_called
|
46
|
+
@when_called
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class Runner
|
51
|
+
def force_args(args)
|
52
|
+
@args = args
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
RSpec.shared_context 'CI_CMD' do
|
58
|
+
# capcmd makes an Open3-ready `murano` command from a list of args.
|
8
59
|
def capcmd(*args)
|
9
|
-
args = [args] unless args.
|
60
|
+
args = [args] unless args.is_a? Array
|
10
61
|
args.flatten!
|
11
62
|
testdir = File.realpath(@testdir.to_s)
|
12
|
-
if ENV['CI_MR_EXE'].nil?
|
63
|
+
if ENV['CI_MR_EXE'].nil?
|
13
64
|
args[0] = File.join(testdir, 'bin', args[0])
|
14
|
-
args.unshift(
|
65
|
+
args.unshift('ruby', "-I#{File.join(testdir, 'lib')}")
|
15
66
|
else
|
16
67
|
args[0] = File.join(testdir, (args[0] + '.exe'))
|
17
68
|
end
|
@@ -20,13 +71,13 @@ RSpec.shared_context "CI_CMD" do
|
|
20
71
|
# The spinner output would make it hard to write expects().
|
21
72
|
args.push '--no-progress'
|
22
73
|
|
23
|
-
if Gem.win_platform?
|
74
|
+
if Gem.win_platform?
|
24
75
|
cmd = args.map do |i|
|
25
76
|
case i
|
26
77
|
when /[ ]/
|
27
|
-
%
|
78
|
+
%("#{i}")
|
28
79
|
when /[\*#]/
|
29
|
-
i.gsub(/([\*#])/,'^\1')
|
80
|
+
i.gsub(/([\*#])/, '^\1')
|
30
81
|
else
|
31
82
|
i
|
32
83
|
end
|
@@ -38,17 +89,9 @@ RSpec.shared_context "CI_CMD" do
|
|
38
89
|
cmd
|
39
90
|
end
|
40
91
|
|
41
|
-
|
42
|
-
#"#{name}-#{Random.new.rand.hash.abs.to_s(16)}"
|
43
|
-
# MUR-2454: Product name may only contain letters and numbers.
|
44
|
-
#"#{name}#{Random.new.rand.hash.abs.to_s(16)}"
|
45
|
-
# MUR-XXXX: Product name must be lowercase.
|
46
|
-
# 2017-06-01: From [cr]: "I'll be having bizapi convert to lower case
|
47
|
-
# in the short term, and pegasus is updating to allow upper case."
|
48
|
-
# LATER: Remove .downcase once PAAS fixed.
|
49
|
-
"#{name.downcase}#{Random.new.rand.hash.abs.to_s(16)}"
|
50
|
-
end
|
92
|
+
# *** Utility fcns: symlinks.
|
51
93
|
|
94
|
+
# Makes a symlink to the /tmp project dir.
|
52
95
|
def mk_symlink
|
53
96
|
# Make it easy to debug tests, e.g., add breakpoint before capcmd('murano', ...)
|
54
97
|
# run test, then open another terminal window and `cd /tmp/murcli-test`.
|
@@ -56,8 +99,8 @@ RSpec.shared_context "CI_CMD" do
|
|
56
99
|
# Since this is for DEVs only, we can hack around this.
|
57
100
|
tmpdir = Dir.tmpdir()
|
58
101
|
return unless tmpdir == '/tmp'
|
59
|
-
@dev_symlink = File.join(tmpdir,
|
60
|
-
FileUtils.rm(@dev_symlink, :
|
102
|
+
@dev_symlink = File.join(tmpdir, 'murcli-test')
|
103
|
+
FileUtils.rm(@dev_symlink, force: true)
|
61
104
|
begin
|
62
105
|
FileUtils.ln_s(Dir.pwd, @dev_symlink)
|
63
106
|
rescue NotImplementedError => err
|
@@ -65,22 +108,220 @@ RSpec.shared_context "CI_CMD" do
|
|
65
108
|
require 'rbconfig'
|
66
109
|
# Check the platform, e.g., "linux-gnu", or other.
|
67
110
|
is_windows = (RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/)
|
68
|
-
|
69
|
-
|
70
|
-
|
111
|
+
unless is_windows
|
112
|
+
$stderr.puts(
|
113
|
+
'Unexpected: ln_s failed on non-Windows machine / ' \
|
114
|
+
"host_os: #{RbConfig::CONFIG['host_os']} / err: #{err}"
|
115
|
+
)
|
116
|
+
end
|
71
117
|
end
|
72
118
|
end
|
73
119
|
|
120
|
+
# Removes the /tmp project directory symlink.
|
74
121
|
def rm_symlink
|
75
|
-
FileUtils.rm(@dev_symlink, :
|
122
|
+
FileUtils.rm(@dev_symlink, force: true) if defined?(@dev_symlink)
|
123
|
+
end
|
124
|
+
|
125
|
+
# *** Utility fcns: Murano Solutions management: create/delete/expunge.
|
126
|
+
|
127
|
+
def murano_solutions_expunge_yes
|
128
|
+
out, err, status = Open3.capture3(
|
129
|
+
capcmd('murano', 'solutions', 'expunge', '-y')
|
130
|
+
)
|
131
|
+
expect(out).to \
|
132
|
+
eq('').or \
|
133
|
+
eq("No solutions found\n").or \
|
134
|
+
match(/^Deleted [\d]+ solutions/)
|
135
|
+
expect(strip_color(err)).to eq('').or eq("No solutions found\n")
|
136
|
+
expect(status.exitstatus).to eq(0).or eq(1)
|
76
137
|
end
|
77
138
|
|
139
|
+
def project_up(skip_link: false)
|
140
|
+
# Preemptive clean up!
|
141
|
+
murano_solutions_expunge_yes if defined?(PRE_EXPUNGE) && PRE_EXPUNGE
|
142
|
+
|
143
|
+
@proj_name_prod = rname('MurCLITestProd')
|
144
|
+
out, err, status = Open3.capture3(
|
145
|
+
capcmd('murano', 'product', 'create', @proj_name_prod, '--save')
|
146
|
+
)
|
147
|
+
expect(err).to eq('')
|
148
|
+
expect(out.chomp).to match(/^[a-zA-Z0-9]+$/)
|
149
|
+
expect(status.exitstatus).to eq(0)
|
150
|
+
|
151
|
+
@proj_name_appy = rname('MurCLITestAppy')
|
152
|
+
out, err, status = Open3.capture3(
|
153
|
+
capcmd('murano', 'application', 'create', @proj_name_appy, '--save')
|
154
|
+
)
|
155
|
+
expect(err).to eq('')
|
156
|
+
soln_id = out
|
157
|
+
expect(soln_id.chomp).to match(/^[a-zA-Z0-9]+$/)
|
158
|
+
expect(status.exitstatus).to eq(0)
|
159
|
+
|
160
|
+
project_up_link unless skip_link
|
161
|
+
end
|
162
|
+
|
163
|
+
def project_up_link
|
164
|
+
out, err, status = Open3.capture3(capcmd('murano', 'assign', 'set'))
|
165
|
+
#expect(out).to a_string_starting_with("Linked product #{@proj_name_prod}")
|
166
|
+
olines = out.lines
|
167
|
+
expect(olines[0].encode!('UTF-8', 'UTF-8')).to eq(
|
168
|
+
"Linked ‘#{@proj_name_prod}’ to ‘#{@proj_name_appy}’\n"
|
169
|
+
)
|
170
|
+
expect(olines[1]).to eq("Created default event handler\n")
|
171
|
+
expect(err).to eq('')
|
172
|
+
expect(status.exitstatus).to eq(0)
|
173
|
+
end
|
174
|
+
|
175
|
+
def project_down
|
176
|
+
return if defined?(PRE_EXPUNGE) && PRE_EXPUNGE
|
177
|
+
|
178
|
+
out, err, status = Open3.capture3(
|
179
|
+
capcmd('murano', 'solution', 'delete', @proj_name_appy, '-y')
|
180
|
+
)
|
181
|
+
expect(out).to eq('')
|
182
|
+
expect(err).to eq('')
|
183
|
+
expect(status.exitstatus).to eq(0)
|
184
|
+
|
185
|
+
out, err, status = Open3.capture3(
|
186
|
+
capcmd('murano', 'solution', 'delete', @proj_name_prod, '-y')
|
187
|
+
)
|
188
|
+
expect(out).to eq('')
|
189
|
+
expect(err).to eq('')
|
190
|
+
expect(status.exitstatus).to eq(0)
|
191
|
+
end
|
192
|
+
|
193
|
+
# Utility fcns: Strings.
|
194
|
+
|
195
|
+
# rname makes a random Murano-acceptable Solution name.
|
196
|
+
def rname(name)
|
197
|
+
#"#{name}-#{Random.new.rand.hash.abs.to_s(16)}"
|
198
|
+
# MUR-2454: Product name may only contain letters and numbers.
|
199
|
+
#"#{name}#{Random.new.rand.hash.abs.to_s(16)}"
|
200
|
+
# MUR-XXXX: Product name must be lowercase.
|
201
|
+
# 2017-06-01: From [cr]: "I'll be having bizapi convert to lower case
|
202
|
+
# in the short term, and pegasus is updating to allow upper case."
|
203
|
+
# LATER: Remove .downcase once PAAS fixed.
|
204
|
+
"#{name.downcase}#{Random.new.rand.hash.abs.to_s(16)}"
|
205
|
+
end
|
206
|
+
|
207
|
+
def strip_color(str)
|
208
|
+
str.gsub(/\e\[(\d+)m/, '')
|
209
|
+
end
|
210
|
+
|
211
|
+
# *** rb-commander goodies
|
212
|
+
|
213
|
+
def murano_command_run(cmd, *args)
|
214
|
+
murano_command_runner(cmd, *args)
|
215
|
+
end
|
216
|
+
|
217
|
+
def murano_command_exits(cmd, *args)
|
218
|
+
murano_command_runner(cmd, *args, wont_run: true)
|
219
|
+
end
|
220
|
+
|
221
|
+
def murano_command_wont_parse(cmd, *args)
|
222
|
+
murano_command_runner(cmd, *args, wont_parse: true)
|
223
|
+
end
|
224
|
+
|
225
|
+
def murano_command_runner(cmd, *args, wont_run: false, wont_parse: false)
|
226
|
+
# This is a functional test, so tell WebMock to back off.
|
227
|
+
# FIXME: Remember the setting and re-enable.
|
228
|
+
WebMock.allow_net_connect!
|
229
|
+
|
230
|
+
wasout = $stdout
|
231
|
+
waserr = $stderr
|
232
|
+
wasterm = $terminal
|
233
|
+
tmpout = StringIO.new
|
234
|
+
tmperr = StringIO.new
|
235
|
+
|
236
|
+
# Commander's `say` calls HighLine's $terminal.say, so redirect that, too.
|
237
|
+
hline = HighLine.new($stdin, tmpout)
|
238
|
+
$terminal = hline
|
239
|
+
# DEVs: If you set a byebug break after this point, the byebug will
|
240
|
+
# show when the code breaks, but you'll see no echo or output. So
|
241
|
+
# comment this code out if you're debugging.
|
242
|
+
$stdout = tmpout
|
243
|
+
$stderr = tmperr
|
244
|
+
|
245
|
+
# When Commander is loaded, it sets an at_exit hook, which we monkey
|
246
|
+
# patch in ReCommander. Since Config.validate_cmd is called before
|
247
|
+
# at_exit, it uses runner.command_exit to tell ReCommander's at_exit
|
248
|
+
# monkey patch not to call Commander.run!. Via rspec, we don't use the
|
249
|
+
# at_exit hook, or ReCommander.
|
250
|
+
$cfg = MrMurano::Config.new(::Commander::Runner.instance)
|
251
|
+
$cfg.load
|
252
|
+
$cfg.validate_cmd(cmd)
|
253
|
+
$cfg['tool.no-progress'] = true
|
254
|
+
runner = ::Commander::Runner.instance
|
255
|
+
unless defined?(runner.command_exit) && runner.command_exit
|
256
|
+
# Commander's at_exit hook calls runner.run! which runs the command
|
257
|
+
# that was determined with Commander was loaded. I [lb] tried a few
|
258
|
+
# different ways to reset Runner.instance, but nothing worked; our
|
259
|
+
# best bet is to just call the command directly.
|
260
|
+
the_cmd = command(cmd.to_sym)
|
261
|
+
when_called = the_cmd.peek_when_called.dup
|
262
|
+
|
263
|
+
runner.force_args(args.dup)
|
264
|
+
$exited_abnormally = true
|
265
|
+
#runner.parse_global_options
|
266
|
+
if wont_parse
|
267
|
+
expect { runner.old_parse_global_options }.to raise_error(SystemExit)
|
268
|
+
else
|
269
|
+
runner.old_parse_global_options
|
270
|
+
runner.remove_global_options runner.options, args
|
271
|
+
if wont_run
|
272
|
+
expect { the_cmd.run(*args) }.to raise_error(SystemExit)
|
273
|
+
else
|
274
|
+
the_cmd.run(*args)
|
275
|
+
end
|
276
|
+
end
|
277
|
+
$exited_abnormally = false
|
278
|
+
|
279
|
+
# Reset proxy_options otherwise Commander::Command.call
|
280
|
+
# uses them the next time this command is called.
|
281
|
+
the_cmd.proxy_options = []
|
282
|
+
the_cmd.when_called = when_called
|
283
|
+
end
|
284
|
+
runner.command_exit = nil
|
285
|
+
|
286
|
+
# Ruby provides std i/o constants, so we could do this:
|
287
|
+
# $stdout, $stderr = STDOUT, STDERR
|
288
|
+
$stdout = wasout
|
289
|
+
$stderr = waserr
|
290
|
+
$terminal = wasterm
|
291
|
+
[strip_color(tmpout.string), strip_color(tmperr.string)]
|
292
|
+
end
|
293
|
+
|
294
|
+
def cmd_verify_help(cmd_name)
|
295
|
+
stdout, stderr = murano_command_run(cmd_name)
|
296
|
+
expect(stdout).to start_with(
|
297
|
+
" NAME:\n\n murano #{cmd_name}\n\n DESCRIPTION:\n\n "
|
298
|
+
)
|
299
|
+
expect(stderr).to eq('')
|
300
|
+
end
|
301
|
+
|
302
|
+
# *** before() and around()
|
303
|
+
|
304
|
+
# Before: Load Config.
|
78
305
|
before(:example) do
|
79
306
|
$cfg = MrMurano::Config.new
|
80
307
|
$cfg.load
|
81
308
|
end
|
82
309
|
|
310
|
+
# Around: Make project dir under /tmp.
|
83
311
|
around(:example) do |ex|
|
312
|
+
# Load the byebug library now, before changing directories.
|
313
|
+
# This sets Setting[:histfile]. Within byebug, try `show histfile`.
|
314
|
+
# Make sure this is set now, otherwise, byebug crashes, e.g.,
|
315
|
+
# <Errno::ENOENT: No such file or directory @ rb_sysopen -
|
316
|
+
# /tmp/d20170830-10087-h7tq6a/project/.byebug_history>
|
317
|
+
# This happens if the first call to byebug is after the chdir.
|
318
|
+
# Byebug creates the histfile in the tmp dir. So the next time
|
319
|
+
# the method containing `byebug` is called, it's from within a
|
320
|
+
# different tmp dir, and the old tmp dir has been removed. So
|
321
|
+
# byebug crashes trying to access the old, missing histfile.
|
322
|
+
require 'byebug/settings/histfile'
|
323
|
+
_ignored = ::Byebug::HistfileSetting::DEFAULT
|
324
|
+
|
84
325
|
@testdir = Pathname.new(Dir.pwd).realpath
|
85
326
|
Dir.mktmpdir do |hdir|
|
86
327
|
ENV['HOME'] = hdir
|
@@ -90,7 +331,8 @@ RSpec.shared_context "CI_CMD" do
|
|
90
331
|
Dir.mkdir(@tmpdir)
|
91
332
|
Dir.chdir(@tmpdir) do
|
92
333
|
mk_symlink
|
93
|
-
Timeout
|
334
|
+
# Timeout after 300 secs/5 mins.
|
335
|
+
Timeout.timeout(300) do
|
94
336
|
ex.run
|
95
337
|
end
|
96
338
|
rm_symlink
|
@@ -100,4 +342,3 @@ RSpec.shared_context "CI_CMD" do
|
|
100
342
|
end
|
101
343
|
end
|
102
344
|
|
103
|
-
# vim: set ai et sw=2 ts=2 :
|