rspec-system 2.2.1 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,31 @@
1
+ 2.3.0
2
+ =====
3
+
4
+ Rework the look and feel to make it pretty and add color
5
+
6
+ This feature release is primarily a look and feel update that improves the visual look of
7
+ how tests run. It changes the way `shell` and `rcp` output looks and includes
8
+ more color where applicable.
9
+
10
+ The output now uses the formatters output methods, in a mildly hackish way so
11
+ that colors can be disabled centrally and also so if users switch to a different
12
+ format the output is silenced. This is useful for cases where you want to run
13
+ the progress formatter without all the extra noise for example.
14
+
15
+ The dividers are now a little better, showing you the begin and end of blocks
16
+ in a better way now, so it is slightly easier to see before/after runs
17
+ without them bleeding into the test parts.
18
+
19
+ As an aside I've also migrated the scp methodology from vsphere to vagrant so
20
+ we are using the same channel to transfer files as well as for sending commands
21
+ which should in theory be a perf boost, but as yet I've seen little evidence.
22
+
23
+ #### Detailed Changes
24
+
25
+ * Rework the look and feel to make it pretty and add color (Ken Barber)
26
+
27
+ -------------------------------
28
+
1
29
  2.2.1
2
30
  =====
3
31
 
@@ -24,7 +24,7 @@ module RSpecSystem
24
24
  def start(count)
25
25
  @max_tests = count
26
26
  super(count)
27
- output << "=================================================================\n\n"
27
+ output << "\n"
28
28
  output << bold("Commencing rspec-system tests\n")
29
29
  output << bold("Total Test Count: ") << color(count, :cyan) << "\n\n"
30
30
  end
@@ -35,7 +35,7 @@ module RSpecSystem
35
35
  # @return [void]
36
36
  def example_started(example)
37
37
  super(example)
38
- output << "=================================================================\n\n"
38
+ output << "\n=begin===========================================================\n\n"
39
39
  output << bold("Running test: ") << "#{next_index} of #{@max_tests}" << "\n"
40
40
  output << bold("Description:\n ") << color(example.full_description, :magenta) << "\n\n"
41
41
  end
@@ -47,6 +47,7 @@ module RSpecSystem
47
47
  def example_passed(example)
48
48
  super(example)
49
49
  output << "\n" << bold('Result: ') << success_color('passed') << "\n\n"
50
+ output << "=end=============================================================\n\n"
50
51
  end
51
52
 
52
53
  # Display output when an example is pending
@@ -58,6 +59,7 @@ module RSpecSystem
58
59
  msg = example.execution_result[:pending_message]
59
60
  output << "\n" << bold('Result: ') << pending_color('pending') << "\n"
60
61
  output << bold("Reason: ") << "#{msg}\n\n"
62
+ output << "=end=============================================================\n\n"
61
63
  end
62
64
 
63
65
  # Display output when an example has failed
@@ -69,6 +71,7 @@ module RSpecSystem
69
71
  msg = example.execution_result[:exception]
70
72
  output << "\n" << bold('Result: ') << failure_color('failed') << "\n"
71
73
  output << bold("Reason:\n") << "#{msg}\n\n"
74
+ output << "=end=============================================================\n\n"
72
75
  end
73
76
 
74
77
  # Obtains next index value so we can keep a count of what test we are upto
@@ -37,7 +37,6 @@ module RSpecSystem::Helpers
37
37
  sp = opts[:sp]
38
38
  dp = opts[:dp]
39
39
 
40
- log.info("rcp from #{sp} to #{d.name}:#{dp} executed")
41
40
  result = ns.rcp(opts)
42
41
  { :success => result }
43
42
  end
@@ -31,6 +31,10 @@ module RSpecSystem::Helpers
31
31
 
32
32
  # Gathers new results by executing the resource action
33
33
  def execute
34
+ dest = opts[:n].name
35
+ cmd = opts[:c]
36
+
37
+ output << bold(color("#{dest}$", :green)) << " #{cmd}\n"
34
38
  rspec_system_node_set.run(opts)
35
39
  end
36
40
  end
@@ -67,20 +67,20 @@ module RSpecSystem::InternalHelpers
67
67
  def start_nodes
68
68
  ns = rspec_system_node_set
69
69
 
70
- puts "Starting nodes"
71
- puts
72
- puts "Setname is: " + ns.setname
73
- puts "Configuration is: " + ns.config.pretty_inspect
74
- puts "Virtual Environment type is: #{ns.env_type}"
75
- puts "Default node is: #{ns.default_node.name}"
76
- puts "Destroy node is: #{ns.destroy}"
77
- puts
78
-
70
+ output << "=begin===========================================================\n"
71
+ output << "\n"
72
+ output << bold("Starting nodes") << "\n"
73
+ output << "\n"
74
+ output << bold("Setname:") << " #{ns.setname}\n"
75
+ output << bold("Configuration:") << " #{ns.config.pretty_inspect}"
76
+ output << bold("Virtual Environment:") << " #{ns.env_type}\n"
77
+ output << bold("Default node:") << " #{ns.default_node.name}\n"
78
+ output << bold("Destroy node:") << " #{ns.destroy}\n"
79
+ output << "\n"
79
80
  ns.setup
80
-
81
- puts
82
- puts "Finished starting nodes"
83
- puts "================================================================="
81
+ output << "\n"
82
+ output << "=end=============================================================\n"
83
+ output << "\n"
84
84
  nil
85
85
  end
86
86
 
@@ -88,11 +88,14 @@ module RSpecSystem::InternalHelpers
88
88
  #
89
89
  # @return [void]
90
90
  def stop_nodes
91
- puts 'Stopping nodes'
92
- puts
91
+ output << "\n"
92
+ output << "=begin===========================================================\n"
93
+ output << "\n"
94
+ output << bold("Stopping nodes\n")
95
+ output << "\n"
93
96
  rspec_system_node_set.teardown
94
- puts 'Finished stopping nodes'
95
- puts "================================================================="
97
+ output << "\n"
98
+ output << "=end=============================================================\n"
96
99
  nil
97
100
  end
98
101
  end
@@ -2,16 +2,80 @@ require 'logger'
2
2
 
3
3
  # This log overlay module, provides access to the +log+ method.
4
4
  module RSpecSystem::Log
5
+ class Logger
6
+ attr_accessor :io
7
+
8
+ def initialize(io)
9
+ @io = io
10
+ end
11
+
12
+ def debug(text)
13
+ io << bold(color('Debug: ', :blue)) << text << "\n"
14
+ end
15
+
16
+ def info(text)
17
+ io << bold('Info: ') << text << "\n"
18
+ end
19
+
20
+ def warn(text)
21
+ io << 'Warn: ' << text << "\n"
22
+ end
23
+
24
+ def fatal(text)
25
+ io << 'Fatal: ' << text << "\n"
26
+ end
27
+
28
+ def unknown(text)
29
+ io << 'Unknown: ' << text << "\n"
30
+ end
31
+
32
+ def error(text)
33
+ io << 'Error: ' << text << "\n"
34
+ end
35
+ end
36
+
5
37
  # Return the default Logger object.
6
38
  #
7
39
  # @return [Logger] default logger object
8
40
  def log
9
41
  return @logger if @logger
10
- @logger = ::Logger.new(STDOUT)
11
- @logger.progname = 'rspec-system'
12
- @logger.formatter = Proc.new do |s, t, p, m|
13
- "#{s}: #{m}\n"
14
- end
42
+ @logger = Logger.new(output)
15
43
  @logger
16
44
  end
45
+
46
+ def formatter
47
+ RSpec.configuration.formatters.each do |f|
48
+ if f.is_a? RSpecSystem::Formatter then
49
+ return f
50
+ end
51
+ end
52
+ end
53
+
54
+ class NullStream
55
+ def <<(o); self; end
56
+ end
57
+
58
+ def output
59
+ begin
60
+ formatter.output
61
+ rescue NameError
62
+ NullStream.new
63
+ end
64
+ end
65
+
66
+ def bold(text)
67
+ begin
68
+ formatter.send(:bold, text)
69
+ rescue NameError
70
+ ""
71
+ end
72
+ end
73
+
74
+ def color(text, color)
75
+ begin
76
+ formatter.send(:color, text, color)
77
+ rescue NameError
78
+ ""
79
+ end
80
+ end
17
81
  end
@@ -127,25 +127,25 @@ module RSpecSystem
127
127
  end
128
128
  channel.on_data do |ch,data|
129
129
  d = data
130
- print d
130
+ output << d
131
131
  r[:stdout]+=d
132
132
  end
133
133
 
134
134
  channel.on_extended_data do |ch,type,data|
135
135
  d = data
136
- print d
136
+ output << d
137
137
  r[:stderr]+=d
138
138
  end
139
139
 
140
140
  channel.on_request("exit-status") do |ch,data|
141
141
  c = data.read_long
142
- puts "Exit code: #{c}"
142
+ output << bold("Exit code:") << " #{c}\n"
143
143
  r[:exit_code] = c
144
144
  end
145
145
 
146
146
  channel.on_request("exit-signal") do |ch, data|
147
147
  s = data.read_string
148
- puts "Exit signal: #{s}"
148
+ output << bold("Exit signal:") << " #{s}\n"
149
149
  r[:exit_signal] = s
150
150
  end
151
151
  end
@@ -19,29 +19,30 @@ module RSpecSystem
19
19
  def initialize(setname, config, custom_prefabs_path, options)
20
20
  super
21
21
  @vagrant_path = File.expand_path(File.join(RSpec.configuration.system_tmp, 'vagrant_projects', setname))
22
+
23
+ RSpec.configuration.rspec_storage[:nodes] ||= {}
22
24
  end
23
25
 
24
26
  # Setup the NodeSet by starting all nodes.
25
27
  #
26
28
  # @return [void]
27
29
  def setup
28
- log.info "[Vagrant#setup] Begin setting up vagrant"
29
-
30
30
  create_vagrantfile()
31
31
 
32
32
  teardown()
33
33
 
34
- log.info "[Vagrant#setup] Running 'vagrant up'"
34
+ output << bold(color("localhost$", :green)) << " vagrant up\n"
35
35
  vagrant("up")
36
36
 
37
37
  # Establish ssh connectivity
38
- ssh_channels = {}
39
38
  nodes.each do |k,v|
40
- log.info "[Vagrant#setup] establishing Net::SSH channel with #{k}"
39
+ output << bold(color("localhost$", :green)) << " ssh #{k}\n"
41
40
  chan = Net::SSH.start(k, 'vagrant', :config => ssh_config)
42
- ssh_channels[k] = chan
41
+
42
+ RSpec.configuration.rspec_storage[:nodes][k] = {
43
+ :ssh => chan,
44
+ }
43
45
  end
44
- RSpec.configuration.ssh_channels = ssh_channels
45
46
 
46
47
  nil
47
48
  end
@@ -50,16 +51,18 @@ module RSpecSystem
50
51
  #
51
52
  # @return [void]
52
53
  def teardown
53
- log.info "[Vagrant#teardown] closing all ssh channels"
54
- RSpec.configuration.ssh_channels.each do |k,v|
55
- v.close unless v.closed?
54
+ nodes.each do |k,v|
55
+ storage = RSpec.configuration.rspec_storage[:nodes][k]
56
+
57
+ next if storage.nil?
58
+
59
+ ssh = storage[:ssh]
60
+ ssh.close unless ssh.closed?
56
61
  end
57
62
 
58
63
  if destroy
59
- log.info "[Vagrant#teardown] Running 'vagrant destroy'"
64
+ output << bold(color("localhost$", :green)) << " vagrant destroy --force\n"
60
65
  vagrant("destroy --force")
61
- else
62
- log.info "[Vagrant#teardown] Skipping 'vagrant destroy'"
63
66
  end
64
67
  nil
65
68
  end
@@ -72,12 +75,8 @@ module RSpecSystem
72
75
  dest = opts[:n].name
73
76
  cmd = opts[:c]
74
77
 
75
- ssh_channels = RSpec.configuration.ssh_channels
76
- puts "-----------------"
77
- puts "#{dest}$ #{cmd}"
78
- result = ssh_exec!(ssh_channels[dest], "cd /tmp && sudo sh -c #{shellescape(cmd)}")
79
- puts "-----------------"
80
- result
78
+ ssh = RSpec.configuration.rspec_storage[:nodes][dest][:ssh]
79
+ ssh_exec!(ssh, "cd /tmp && sudo sh -c #{shellescape(cmd)}")
81
80
  end
82
81
 
83
82
  # Transfer files to a host in the NodeSet.
@@ -88,8 +87,6 @@ module RSpecSystem
88
87
  # path then move it later. Its slow and brittle and we need a better
89
88
  # solution. Its also very Linux-centrix in its use of temp dirs.
90
89
  def rcp(opts)
91
- #log.debug("[Vagrant@rcp] called with #{opts.inspect}")
92
-
93
90
  dest = opts[:d].name
94
91
  source = opts[:sp]
95
92
  dest_path = opts[:dp]
@@ -98,23 +95,13 @@ module RSpecSystem
98
95
  tmpdest = tmppath
99
96
 
100
97
  # Do the copy and print out results for debugging
101
- cmd = "scp -r -F '#{ssh_config}' '#{source}' #{dest}:#{tmpdest}"
102
- puts "------------------"
103
- puts "localhost$ #{cmd}"
104
- r = systemu cmd
105
-
106
- result = {
107
- :exit_code => r[0].exitstatus,
108
- :stdout => r[1],
109
- :stderr => r[2]
110
- }
111
-
112
- print "#{result[:stdout]}"
113
- print "#{result[:stderr]}"
114
- puts "Exit code: #{result[:exit_code]}"
98
+ cmd = "scp -r '#{source}' #{dest}:#{tmpdest}"
99
+ output << bold(color("localhost$", :green)) << " #{cmd}\n"
100
+ ssh = RSpec.configuration.rspec_storage[:nodes][dest][:ssh]
101
+ ssh.scp.upload! source.to_s, tmpdest.to_s, :recursive => true
115
102
 
116
103
  # Now we move the file into their final destination
117
- result = run(:n => opts[:d], :c => "mv #{tmpdest} #{dest_path}")
104
+ result = shell(:n => opts[:d], :c => "mv #{tmpdest} #{dest_path}")
118
105
  if result[:exit_code] == 0
119
106
  return true
120
107
  else
@@ -126,13 +113,11 @@ module RSpecSystem
126
113
  #
127
114
  # @api private
128
115
  def create_vagrantfile
129
- log.info "[Vagrant#create_vagrantfile] Creating vagrant file here: #{@vagrant_path}"
116
+ output << bold(color("localhost$", :green)) << " cd #{@vagrant_path}\n"
130
117
  FileUtils.mkdir_p(@vagrant_path)
131
118
  File.open(File.expand_path(File.join(@vagrant_path, "Vagrantfile")), 'w') do |f|
132
119
  f.write('Vagrant.configure("2") do |c|' + "\n")
133
120
  nodes.each do |k,v|
134
- log.debug "Filling in content for #{k}"
135
-
136
121
  ps = v.provider_specifics['vagrant']
137
122
 
138
123
  node_config = " c.vm.define '#{k}' do |v|\n"
@@ -148,7 +133,6 @@ module RSpecSystem
148
133
  end
149
134
  f.write("end\n")
150
135
  end
151
- log.debug "[Vagrant#create_vagrantfile] Finished creating vagrant file"
152
136
  nil
153
137
  end
154
138
 
@@ -167,7 +151,6 @@ module RSpecSystem
167
151
  self.nodes.each do |k,v|
168
152
  Dir.chdir(@vagrant_path) do
169
153
  result = systemu("vagrant ssh-config #{k} >> #{ssh_config_path}")
170
- puts result.inspect
171
154
  end
172
155
  end
173
156
  ssh_config_path
@@ -37,8 +37,6 @@ module RSpecSystem
37
37
  #
38
38
  # @return [void]
39
39
  def setup
40
- log.info "[Vsphere#setup] Setup begins"
41
-
42
40
  dest_dir = ENV['RSPEC_VSPHERE_DEST_DIR']
43
41
  template_dir = ENV['RSPEC_VSPHERE_TEMPLATE_DIR']
44
42
 
@@ -56,7 +54,7 @@ module RSpecSystem
56
54
  vm_folder = dc.vmFolder
57
55
  vm_newfolder = vm_folder.find(dest_dir)
58
56
 
59
- log.info "[Vsphere#setup] launching instances one by one"
57
+ log.info "Launching VSphere instances one by one"
60
58
  nodes.each do |k,v|
61
59
  ps = v.provider_specifics['vsphere']
62
60
 
@@ -66,7 +64,7 @@ module RSpecSystem
66
64
 
67
65
  raise "No template specified for this prefab" if template.nil?
68
66
 
69
- log.info "[Vsphere#setup] launching instance #{k} with template #{template}"
67
+ log.info "Launching VSphere instance #{k} with template #{template}"
70
68
 
71
69
  vm = vm_folder.find(ENV['RSPEC_VSPHERE_TEMPLATE_DIR']).find(template)
72
70
 
@@ -74,7 +72,7 @@ module RSpecSystem
74
72
 
75
73
  vm_name = "rspec-system-#{k}-#{random_string(10)}"
76
74
 
77
- log.info "[Vsphere#setup] Cloning new vm #{vm_name} in folder #{dest_dir}"
75
+ log.info "Cloning new VSphere vm #{vm_name} in folder #{dest_dir}"
78
76
 
79
77
  vm.CloneVM_Task(
80
78
  :folder => vm_newfolder,
@@ -82,7 +80,7 @@ module RSpecSystem
82
80
  :spec => spec
83
81
  ).wait_for_completion
84
82
 
85
- log.info "[Vsphere#setup] Cloning complete"
83
+ log.info "Cloning complete"
86
84
 
87
85
  newvm = vm_newfolder.find(vm_name)
88
86
  guest_info = newvm.guest
@@ -90,20 +88,20 @@ module RSpecSystem
90
88
  timeout(60) do
91
89
  while(newvm.guest.guestState != 'running') do
92
90
  sleep 2
93
- puts "#{k}> Waiting for vm to run ..."
91
+ log.info "#{k}> Waiting for vm to run ..."
94
92
  end
95
93
  end
96
94
 
97
95
  timeout(60) do
98
96
  while(newvm.guest.ipAddress == nil) do
99
97
  sleep 2
100
- puts "#{k}> Waiting for ip address ..."
98
+ log.info "#{k}> Waiting for ip address ..."
101
99
  end
102
100
  end
103
101
 
104
102
  ipaddress = newvm.guest.ipAddress
105
103
 
106
- log.info "[Vsphere#setup] establishing Net::SSH channel with #{k}"
104
+ output << bold(color("localhost$", :green)) << " ssh #{k}"
107
105
  chan = Net::SSH.start(ipaddress, 'vagrant', :password => 'vagrant')
108
106
 
109
107
  RSpec.configuration.rspec_storage[:nodes][k] = {
@@ -111,11 +109,8 @@ module RSpecSystem
111
109
  :ssh => chan,
112
110
  :vm => newvm
113
111
  }
114
- log.info "[Vsphere#setup] Node launched: #{k}"
115
112
  end
116
113
 
117
- log.info("[Vsphere#setup] setup complete")
118
-
119
114
  nil
120
115
  end
121
116
 
@@ -127,25 +122,23 @@ module RSpecSystem
127
122
  storage = RSpec.configuration.rspec_storage[:nodes][k]
128
123
 
129
124
  if storage.nil?
130
- log.info "[Vsphere#teardown] No entry for node #{k}, no teardown necessary"
125
+ log.info "No entry for node #{k}, no teardown necessary"
131
126
  next
132
127
  end
133
128
 
134
- log.info "[Vsphere#teardown] closing ssh channel to #{k}"
135
129
  ssh = storage[:ssh]
136
130
  ssh.close unless ssh.closed?
137
131
 
138
132
  if destroy
139
- log.info "[Vsphere#teardown] destroy instance #{k}"
133
+ log.info "Destroying instance #{k}"
140
134
  vm = storage[:vm]
141
135
  if vm == nil
142
- puts "No vm object"
136
+ log.error "No vm object for #{k}"
143
137
  next
144
138
  end
145
139
  vm.PowerOffVM_Task.wait_for_completion
146
140
  vm.Destroy_Task.wait_for_completion
147
141
  else
148
- log.info "[Vsphere#teardown] Skipping destroy instance #{k}"
149
142
  next
150
143
  end
151
144
  end
@@ -162,11 +155,7 @@ module RSpecSystem
162
155
  cmd = opts[:c]
163
156
 
164
157
  ssh = RSpec.configuration.rspec_storage[:nodes][dest][:ssh]
165
- puts "-----------------"
166
- puts "#{dest}$ #{cmd}"
167
- result = ssh_exec!(ssh, "cd /tmp && sudo sh -c '#{cmd}'")
168
- puts "-----------------"
169
- result
158
+ ssh_exec!(ssh, "cd /tmp && sudo sh -c '#{cmd}'")
170
159
  end
171
160
 
172
161
  # Transfer files to a host in the NodeSet.
@@ -177,8 +166,6 @@ module RSpecSystem
177
166
  # path then move it later. Its slow and brittle and we need a better
178
167
  # solution. Its also very Linux-centrix in its use of temp dirs.
179
168
  def rcp(opts)
180
- #log.debug("[Vagrant@rcp] called with #{opts.inspect}")
181
-
182
169
  dest = opts[:d].name
183
170
  source = opts[:sp]
184
171
  dest_path = opts[:dp]
@@ -29,20 +29,19 @@ RSpec.configure do |c|
29
29
  begin
30
30
  start_nodes
31
31
  rescue => ex
32
- puts ex.inspect + " in"
33
- puts ex.backtrace.join("\n ")
32
+ output << ex.inspect + " in\n"
33
+ output << ex.backtrace.join("\n ") << "\n"
34
34
  exit(1)
35
35
  end
36
36
  end
37
37
 
38
38
  c.after :suite do
39
- puts "================================================================="
40
39
  # After Suite exceptions get captured it seems
41
40
  begin
42
41
  stop_nodes
43
42
  rescue => ex
44
- puts ex.inspect + " in"
45
- puts ex.backtrace.join("\n ")
43
+ output << ex.inspect + " in\n"
44
+ output << ex.backtrace.join("\n ") << "\n"
46
45
  end
47
46
  end
48
47
  end
data/rspec-system.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
  Gem::Specification.new do |s|
3
3
  # Metadata
4
4
  s.name = "rspec-system"
5
- s.version = "2.2.1"
5
+ s.version = "2.3.0"
6
6
  s.authors = ["Ken Barber"]
7
7
  s.email = ["info@puppetlabs.com"]
8
8
  s.homepage = "https://github.com/puppetlabs/rspec-system"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-system
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.1
4
+ version: 2.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-09-11 00:00:00.000000000 Z
12
+ date: 2013-09-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
@@ -217,4 +217,3 @@ test_files:
217
217
  - spec/unit/kwalify-schemas/prefabs_schema_spec.rb
218
218
  - spec/unit/result_spec.rb
219
219
  - spec/unit/utils_spec.rb
220
- has_rdoc: