MuranoCLI 3.0.1 → 3.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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 :
|