test-kitchen 1.0.0.alpha.0 → 1.0.0.alpha.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -184,12 +184,15 @@ module Kitchen
184
184
  #
185
185
  # **Note** This method calls exec and will not return.
186
186
  #
187
+ # @see Driver::LoginCommand
187
188
  # @see Driver::Base#login_command
188
189
  def login
189
- command, *args = driver.login_command(state_file.read)
190
+ login_command = driver.login_command(state_file.read)
191
+ command, *args = login_command.cmd_array
192
+ options = login_command.options
190
193
 
191
- debug("Login command: #{command} #{args.join(' ')}")
192
- Kernel.exec(command, *args)
194
+ debug("Login command: #{command} #{args.join(' ')} (Options: #{options})")
195
+ Kernel.exec(command, *args, options)
193
196
  end
194
197
 
195
198
  def last_action
@@ -97,7 +97,7 @@ module Kitchen
97
97
  return Hash.new if string.nil? || string.empty?
98
98
 
99
99
  ::YAML.safe_load(string)
100
- rescue SyntaxError => ex
100
+ rescue SyntaxError, Psych::SyntaxError => ex
101
101
  raise UserError, "Error parsing #{file_name} (#{ex.message})"
102
102
  end
103
103
  end
@@ -32,20 +32,43 @@ module Kitchen
32
32
  # Executes a command in a subshell on the local running system.
33
33
  #
34
34
  # @param cmd [String] command to be executed locally
35
- # @param use_sudo [TrueClass, FalseClass] whether or not to use sudo
36
- # @param log_subject [String] used in the output or log header for clarity
37
- # and context
35
+ # @param options [Hash] additional configuration of command
36
+ # @option options [TrueClass, FalseClass] :use_sudo whether or not to use
37
+ # sudo
38
+ # @option options [String] :log_subject used in the output or log header
39
+ # for clarity and context. Default is "local".
40
+ # @option options [TrueClass, FalseClass] :quiet whether or not to echo
41
+ # logging commands. Default is false.
42
+ # @option options [String] :cwd the directory to chdir to before running
43
+ # the command
44
+ # @option options [Hash] :environment a Hash of environment variables to
45
+ # set before the command is run. By default, the environment will
46
+ # *always* be set to 'LC_ALL' => 'C' to prevent issues with multibyte
47
+ # characters in Ruby 1.8. To avoid this, use :environment => nil for
48
+ # *no* extra environment settings, or
49
+ # :environment => {'LC_ALL'=>nil, ...} to set other environment settings
50
+ # without changing the locale.
51
+ # @option options [Integer] :timeout Numeric value for the number of
52
+ # seconds to wait on the child process before raising an Exception.
53
+ # This is calculated as the total amount of time that ShellOut waited on
54
+ # the child process without receiving any output (i.e., IO.select
55
+ # returned nil). Default is 60000 seconds. Note: the stdlib Timeout
56
+ # library is not used.
57
+ # @return [String] the standard output of the command as a String
38
58
  # @raise [ShellCommandFailed] if the command fails
39
59
  # @raise [Error] for all other unexpected exceptions
40
- def run_command(cmd, use_sudo = false, log_subject = "local")
60
+ def run_command(cmd, options = {})
61
+ use_sudo = options[:use_sudo].nil? ? false : options[:use_sudo]
62
+ quiet = options[:quiet]
41
63
  cmd = "sudo #{cmd}" if use_sudo
42
- subject = "[#{log_subject} command]"
64
+ subject = "[#{options[:log_subject] || "local"} command]"
43
65
 
44
- info("#{subject} BEGIN (#{display_cmd(cmd)})")
45
- sh = Mixlib::ShellOut.new(cmd, :live_stream => logger, :timeout => 60000)
66
+ info("#{subject} BEGIN (#{display_cmd(cmd)})") unless quiet
67
+ sh = Mixlib::ShellOut.new(cmd, shell_opts(options))
46
68
  sh.run_command
47
- info("#{subject} END #{Util.duration(sh.execution_time)}")
69
+ info("#{subject} END #{Util.duration(sh.execution_time)}") unless quiet
48
70
  sh.error!
71
+ sh.stdout
49
72
  rescue Mixlib::ShellOut::ShellCommandFailed => ex
50
73
  raise ShellCommandFailed, ex.message
51
74
  rescue Exception => error
@@ -61,5 +84,12 @@ module Kitchen
61
84
 
62
85
  newline == "\n" ? "#{first_line}\\n...#{last_char}" : cmd
63
86
  end
87
+
88
+ def shell_opts(options)
89
+ filtered_opts = options.reject do |key, value|
90
+ [:use_sudo, :log_subject, :quiet].include?(key)
91
+ end
92
+ { :live_stream => logger, :timeout => 60000 }.merge(filtered_opts)
93
+ end
64
94
  end
65
95
  end
@@ -77,7 +77,7 @@ module Kitchen
77
77
 
78
78
  def deserialize_string(string)
79
79
  ::YAML.safe_load(string)
80
- rescue SyntaxError => ex
80
+ rescue SyntaxError, Psych::SyntaxError => ex
81
81
  raise StateFileLoadError, "Error parsing #{file_name} (#{ex.message})"
82
82
  end
83
83
 
@@ -18,5 +18,5 @@
18
18
 
19
19
  module Kitchen
20
20
 
21
- VERSION = "1.0.0.alpha.0"
21
+ VERSION = "1.0.0.alpha.1"
22
22
  end
@@ -148,7 +148,8 @@ describe Kitchen::Config do
148
148
  ]
149
149
  })
150
150
  config.instances.size.must_equal 5
151
- config.instances.map { |i| i.name }.must_equal %w{s1-p1 s1-p2 s2-p1 s2-p2 s3-p2}
151
+ instance_names = config.instances.map { |i| i.name }
152
+ instance_names.must_equal %w{s1-p1 s1-p2 s2-p1 s2-p2 s3-p2}
152
153
  end
153
154
 
154
155
  it "returns an instance containing a driver instance" do
@@ -28,7 +28,7 @@ end
28
28
 
29
29
  describe Kitchen::StateFile do
30
30
 
31
- let(:state_file) { Kitchen::StateFile.new('/tmp', 'oftheunion')}
31
+ let(:state_file) { Kitchen::StateFile.new('/tmp', 'oftheunion') }
32
32
  let(:file_name) { '/tmp/.kitchen/oftheunion.yml' }
33
33
 
34
34
  before do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: test-kitchen
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.alpha.0
4
+ version: 1.0.0.alpha.1
5
5
  prerelease: 6
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-03-02 00:00:00.000000000 Z
12
+ date: 2013-03-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: celluloid
@@ -326,14 +326,17 @@ files:
326
326
  - .gitignore
327
327
  - .travis.yml
328
328
  - .yardopts
329
+ - CHANGELOG.md
329
330
  - Gemfile
330
331
  - Guardfile
331
332
  - LICENSE
332
333
  - README.md
333
334
  - Rakefile
334
335
  - bin/kitchen
335
- - features/cli.feature
336
- - features/cli_init.feature
336
+ - features/kitchen_command.feature
337
+ - features/kitchen_driver_discover_command.feature
338
+ - features/kitchen_init_command.feature
339
+ - features/step_definitions/gem_steps.rb
337
340
  - features/support/env.rb
338
341
  - lib/kitchen.rb
339
342
  - lib/kitchen/busser.rb
@@ -347,6 +350,8 @@ files:
347
350
  - lib/kitchen/driver/dummy.rb
348
351
  - lib/kitchen/driver/ssh_base.rb
349
352
  - lib/kitchen/errors.rb
353
+ - lib/kitchen/generator/init.rb
354
+ - lib/kitchen/generator/new_plugin.rb
350
355
  - lib/kitchen/instance.rb
351
356
  - lib/kitchen/instance_actor.rb
352
357
  - lib/kitchen/loader/yaml.rb
@@ -407,8 +412,10 @@ signing_key:
407
412
  specification_version: 3
408
413
  summary: A Chef convergence integration test harness
409
414
  test_files:
410
- - features/cli.feature
411
- - features/cli_init.feature
415
+ - features/kitchen_command.feature
416
+ - features/kitchen_driver_discover_command.feature
417
+ - features/kitchen_init_command.feature
418
+ - features/step_definitions/gem_steps.rb
412
419
  - features/support/env.rb
413
420
  - spec/kitchen/collection_spec.rb
414
421
  - spec/kitchen/color_spec.rb
data/features/cli.feature DELETED
@@ -1,17 +0,0 @@
1
- Feature: Ensure that the Command Line Interface works as designed
2
- In order to test code via CLI
3
- As an Operator
4
- I want to run the CLI with different arguments
5
-
6
- Scenario: Running the help command exits cleanly
7
- When I successfully run `kitchen help`
8
- Then the exit status should be 0
9
- And the output should contain "kitchen console"
10
- And a file named ".kitchen/logs/kitchen.log" should exist
11
-
12
- Scenario: Show the version number
13
- When I successfully run `kitchen version`
14
- Then the exit status should be 0
15
-
16
-
17
-
@@ -1,156 +0,0 @@
1
- Feature: Ensure that the Command Line Interface init creates the correct files
2
- In order to initialize an un-Kitchenified cookbook
3
- As an Operator
4
- I want to initialize a cookbook
5
-
6
-
7
- @ok
8
- Scenario: Basic init with no extras succeeds
9
- When I run `kitchen init` interactively
10
- And I type "n"
11
- Then the exit status should be 0
12
- And a directory named ".kitchen" should exist
13
- And a directory named "test/integration/default" should exist
14
- And the file ".gitignore" should contain:
15
- """
16
- .kitchen/
17
- .kitchen.local.yml
18
- """
19
- And the file ".kitchen.yml" should contain:
20
- """
21
- ---
22
- driver_plugin: vagrant
23
- platforms:
24
- - name: ubuntu-12.04
25
- driver_config:
26
- box: opscode-ubuntu-12.04
27
- box_url: https://opscode-vm.s3.amazonaws.com/vagrant/boxes/opscode-ubuntu-12.04.box
28
- run_list:
29
- - recipe[apt]
30
- - name: ubuntu-10.04
31
- driver_config:
32
- box: opscode-ubuntu-10.04
33
- box_url: https://opscode-vm.s3.amazonaws.com/vagrant/boxes/opscode-ubuntu-10.04.box
34
- run_list:
35
- - recipe[apt]
36
- - name: centos-6.3
37
- driver_config:
38
- box: opscode-centos-6.3
39
- box_url: https://opscode-vm.s3.amazonaws.com/vagrant/boxes/opscode-centos-6.3.box
40
- run_list:
41
- - recipe[yum::epel]
42
- - name: centos-5.8
43
- driver_config:
44
- box: opscode-centos-5.8
45
- box_url: https://opscode-vm.s3.amazonaws.com/vagrant/boxes/opscode-centos-5.8.box
46
- run_list:
47
- - recipe[yum::epel]
48
- suites:
49
- - name: default
50
- run_list: []
51
- attributes: {}
52
- """
53
- And a file named "Gemfile" should not exist
54
- And a file named "Rakefile" should not exist
55
- And a file named "Thorfile" should not exist
56
-
57
-
58
-
59
- @ok
60
- Scenario: Running with a Rakefile file appends Kitchen tasks
61
- Given an empty file named "Rakefile"
62
- When I run `kitchen init` interactively
63
- And I type "n"
64
- Then the exit status should be 0
65
- And the file "Rakefile" should contain exactly:
66
- """
67
-
68
- begin
69
- require 'kitchen/rake_tasks'
70
- Kitchen::RakeTasks.new
71
- rescue LoadError
72
- puts ">>>>> Kitchen gem not loaded, omitting tasks" unless ENV['CI']
73
- end
74
-
75
- """
76
-
77
-
78
- @ok
79
- Scenario: Running with a Thorfile file appends Kitchen tasks
80
- Given an empty file named "Thorfile"
81
- When I run `kitchen init` interactively
82
- And I type "n"
83
- Then the exit status should be 0
84
- And the file "Thorfile" should contain exactly:
85
- """
86
-
87
- begin
88
- require 'kitchen/thor_tasks'
89
- Kitchen::ThorTasks.new
90
- rescue LoadError
91
- puts ">>>>> Kitchen gem not loaded, omitting tasks" unless ENV['CI']
92
- end
93
-
94
- """
95
-
96
-
97
- @ok
98
- Scenario: Listing the drivers provides correct output, does not write Gemfile
99
- When I run `kitchen init` interactively
100
- And I type "y"
101
- And I type "list"
102
- And I type "skip"
103
- Then the exit status should be 0
104
- And a file named ".kitchen.yml" should exist
105
- And a directory named ".kitchen" should exist
106
- And a file named "Gemfile" should not exist
107
-
108
-
109
- @ok
110
- Scenario: Running the init command without a Gemfile provides warning and fails
111
- When I run `kitchen init` interactively
112
- And I type "y"
113
- And I type "kitchen-vagrant"
114
- And the output should contain "You do not have an existing Gemfile"
115
- Then the exit status should be 1
116
-
117
-
118
- @ok
119
- Scenario: Running the init command succeeds
120
- Given an empty file named "Gemfile"
121
- When I run `kitchen init` interactively
122
- And I type "y"
123
- And I type "kitchen-vagrant"
124
- Then the exit status should be 0
125
- And the output should contain "You must run `bundle install' to fetch any new gems."
126
- And a file named ".kitchen.yml" should exist
127
- And a file named ".gitignore" should exist
128
- And the file "Gemfile" should contain "gem 'kitchen-vagrant', :group => :integration"
129
-
130
-
131
- @ok
132
- Scenario: Running init with a correct metadata.rb works
133
- Given a file named "metadata.rb" with:
134
- """
135
- name "ntp"
136
- license "Apache 2.0"
137
- description "Installs and configures ntp as a client or server"
138
- version "0.1.0"
139
- recipe "ntp", "Installs and configures ntp either as a server or client"
140
-
141
- %w{ ubuntu debian redhat centos fedora scientific amazon oracle freebsd }.each do |os|
142
- supports os
143
- end
144
- """
145
- When I run `kitchen init` interactively
146
- And I type "n"
147
- Then the exit status should be 0
148
- And the file ".kitchen.yml" should contain:
149
- """
150
- suites:
151
- - name: default
152
- run_list:
153
- - recipe[ntp]
154
- attributes: {}
155
- """
156
-