jenkins-bot has submitted this change and it was merged.

Change subject: plugin: Acceptance tests for `vagrant config`
......................................................................


plugin: Acceptance tests for `vagrant config`

Implemented functional acceptance tests for `vagrant config` using
Cucumber as the test framework and Aruba for command execution and I/O
simulation. The latter had some issues when dealing with commands that
require a terminal, so additional test helpers were implemented using
Ruby's native PTY support.

Setup of the test mw-vagrant environment relies on rsync to copy the
contents of the local working directory into a temporary directory,
excluding all git-ignored files.

Bug: T89489
Change-Id: I352267bb591f8de911a11072954f337ebbea89c7
---
M Gemfile
A features/step_definitions/common_steps.rb
A features/step_definitions/settings_steps.rb
A features/support/env.rb
A features/support/hooks.rb
A features/support/interactive_helper.rb
A features/support/output_helper.rb
A features/vagrant_config.feature
M mediawiki-vagrant.gemspec
9 files changed, 276 insertions(+), 1 deletion(-)

Approvals:
  Dduvall: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/Gemfile b/Gemfile
index 01566f1..3fdbe2c 100644
--- a/Gemfile
+++ b/Gemfile
@@ -6,6 +6,7 @@
 end
 
 group :development, :test do
+  gem 'fakefs', '~> 0.6.5'
   gem 'pry-byebug'
 end
 
diff --git a/features/step_definitions/common_steps.rb 
b/features/step_definitions/common_steps.rb
new file mode 100644
index 0000000..2a4fc6c
--- /dev/null
+++ b/features/step_definitions/common_steps.rb
@@ -0,0 +1,47 @@
+require 'mediawiki-vagrant/environment'
+
+When(/^I enter the following at each prompt:$/) do |inputs|
+  inputs = inputs.rows_hash
+  prompt_pattern = /(#{inputs.keys.join('|')})/
+
+  inputs.values.each do |input|
+    matches = expect_pty_output(prompt_pattern)
+    type_on_pty(inputs[matches[1]])
+  end
+end
+
+When(/^I run vagrant with `([^`]+)`( interactively)?$/) do |arguments, 
interactively|
+  cmd = "#{@bundle} exec vagrant #{arguments}"
+
+  if interactively.nil?
+    run_simple(cmd, false)
+  else
+    run_with_pty(cmd)
+  end
+end
+
+Then(/^the command should have completed successfully$/) do
+  if pty_process?
+    expect(status_of_pty_process.exitstatus).to eq(0)
+  else
+    assert_success(true)
+  end
+end
+
+Then(/^the (\w+) column of output should contain "([^"]+)"$/) do |col, output|
+  expect(output_column(col)).to include(output)
+end
+
+Then(/^the (\w+) column of output should contain:$/) do |col, output|
+  output = output.respond_to?(:raw) ? output.raw : [[output]]
+  column = output_column(col)
+
+  output.each { |(value)| expect(column).to include(value) }
+end
+
+Then(/^the tabular output should contain:$/) do |table|
+  rows = table.raw
+  output = output_table(rows.first.length)
+
+  rows.each { |row| expect(output).to include(row) }
+end
diff --git a/features/step_definitions/settings_steps.rb 
b/features/step_definitions/settings_steps.rb
new file mode 100644
index 0000000..39af3d9
--- /dev/null
+++ b/features/step_definitions/settings_steps.rb
@@ -0,0 +1,40 @@
+require 'mediawiki-vagrant/settings/definitions'
+
+Given(/^the "([^"]+)" setting is "([^"]+)"$/) do |name, value|
+  @env.configure_settings do |settings|
+    settings[name] = value
+  end
+end
+
+Given(/^the "([^"]+)" setting is not configured$/) do |name|
+  @env.configure_settings do |settings|
+    settings.setting(name).unset!
+  end
+end
+
+Then(/^the "([^"]+)" setting should be "([^"]+)"$/) do |name, value|
+  settings = @env.load_settings
+
+  setting = settings.setting(name)
+  existing_value = setting.value
+  setting.value = value
+
+  expect(existing_value).to eq(setting.value)
+end
+
+Then(/^the "([^"]+)" setting should not be configured$/) do |name|
+  settings = @env.load_settings
+  expect(settings[name]).to be(nil)
+end
+
+Then(/^the current settings should be:$/) do |table|
+  settings = @env.load_settings
+
+  table.raw.each do |(name, value)|
+    setting = settings.setting(name)
+    existing_value = setting.value
+    setting.value = value
+
+    expect(existing_value).to eq(setting.value)
+  end
+end
diff --git a/features/support/env.rb b/features/support/env.rb
new file mode 100644
index 0000000..8c3ec70
--- /dev/null
+++ b/features/support/env.rb
@@ -0,0 +1,7 @@
+require 'aruba/cucumber'
+
+require_relative 'interactive_helper'
+require_relative 'output_helper'
+
+World(MediaWikiVagrant::InteractiveHelper)
+World(MediaWikiVagrant::OutputHelper)
diff --git a/features/support/hooks.rb b/features/support/hooks.rb
new file mode 100644
index 0000000..a00d34b
--- /dev/null
+++ b/features/support/hooks.rb
@@ -0,0 +1,34 @@
+Before do
+  @aruba_timeout_seconds = 10
+
+  # Create a clean environment for each scenario by copying the working
+  # directory to Aruba's temporary location
+  @env = MediaWikiVagrant::Environment.new(absolute_path('mwv'))
+
+  excludes = "--exclude=/Gemfile --exclude=/vendor --exclude=/.git"
+  system("rsync -a #{excludes} --filter='dir-merge,- .gitignore' ./ 
'#{absolute_path("mwv")}/'")
+  create_dir('home')
+
+  set_env('HOME', absolute_path('home'))
+  set_env('VAGRANT_HOME', absolute_path('mwv'))
+
+  # Be sure to mute warnings about running vagrant through bundler
+  set_env('VAGRANT_I_KNOW_WHAT_IM_DOING_PLEASE_BE_QUIET', 'true')
+
+  cd('mwv')
+
+  # Check for a locally installed bundler
+  if File.exist?('vendor/bin/bundle')
+    @bundle = File.expand_path('vendor/bin/bundle')
+  else
+    @bundle = 'bundle'
+  end
+end
+
+After do
+  # Clean up as best we can
+  begin
+    @env.path.rmtree
+  rescue Errno::ENOTEMPTY, Errno::EBUSY
+  end
+end
diff --git a/features/support/interactive_helper.rb 
b/features/support/interactive_helper.rb
new file mode 100644
index 0000000..d06e511
--- /dev/null
+++ b/features/support/interactive_helper.rb
@@ -0,0 +1,55 @@
+require 'expect'
+require 'io/console'
+require 'pty'
+require 'timeout'
+
+require 'pry-byebug'
+
+module MediaWikiVagrant
+  module InteractiveHelper
+    def run_with_pty(cmd)
+      in_current_dir do
+        @pty_out, @pty_in, @pty_pid = PTY.spawn(cmd)
+        @pty_output = ''
+      end
+    end
+
+    def expect_pty_output(pattern, timeout: 5)
+      result = pty_operation { @pty_out.expect(pattern, timeout) }
+      raise "command didn't output `#{pattern}` within #{timeout} seconds" if 
result.nil?
+      @pty_output.concat(result.first)
+      result
+    end
+
+    def pty_output
+      output = pty_operation { @pty_out.read }
+      @pty_output.concat(output) unless output.nil?
+      @pty_output
+    end
+
+    def pty_process?
+      !@pty_pid.nil?
+    end
+
+    def type_on_pty(input)
+      @pty_in.puts(input)
+    end
+
+    def status_of_pty_process
+      @pty_pid, @pty_status = Timeout.timeout(5) do
+        pty_output
+        Process.wait2(@pty_pid)
+      end
+
+      @pty_status
+    end
+
+    private
+
+    def pty_operation
+      yield
+    rescue Errno::EIO
+      nil
+    end
+  end
+end
diff --git a/features/support/output_helper.rb 
b/features/support/output_helper.rb
new file mode 100644
index 0000000..81d9176
--- /dev/null
+++ b/features/support/output_helper.rb
@@ -0,0 +1,12 @@
+module MediaWikiVagrant
+  module OutputHelper
+    def output_column(column)
+      column = [:first, :second, :third, :forth].index(column.to_sym) if 
column.is_a?(String)
+      all_output.lines.map { |line| line.split[column] }
+    end
+
+    def output_table(width)
+      all_output.lines.map { |line| line.split(/[ \t]+/, width).map(&:strip) }
+    end
+  end
+end
diff --git a/features/vagrant_config.feature b/features/vagrant_config.feature
new file mode 100644
index 0000000..fadf855
--- /dev/null
+++ b/features/vagrant_config.feature
@@ -0,0 +1,79 @@
+Feature: Command line configuration via `vagrant config`
+
+  Simple VM configurations should be manageable from the command line so that
+  developers can easily fine tune settings that are appropriate to their
+  systems and workflows.
+
+  Scenario: Running `vagrant list-commands` includes `config`
+    When I run vagrant with `list-commands`
+    Then the tabular output should contain:
+      | config | configures mediawiki-vagrant settings |
+
+  Scenario: Running `vagrant config --help` prints usage
+    When I run vagrant with `config --help`
+    Then the output should contain:
+      """
+      Usage: vagrant config [options] [name] [value]
+      """
+
+  Scenario: Running `vagrant config --list` lists available settings
+    When I run vagrant with `config --list`
+    Then the first column of output should contain:
+      | git_user      |
+      | vagrant_ram   |
+      | vagrant_cores |
+      | static_ip     |
+      | http_port     |
+      | nfs_shares    |
+      | forward_agent |
+      | forward_x11   |
+
+  Scenario: Running `vagrant config name value` configures a setting
+    When I run vagrant with `config foo bar`
+    Then the "foo" setting should be "bar"
+
+  Scenario: Running `vagrant config --get name` outputs a setting
+    Given the "foo" setting is "bar"
+    When I run vagrant with `config --get foo`
+    Then the output should contain "bar"
+
+  Scenario: Running `vagrant config --unset name` removes a setting
+    Given the "foo" setting is "bar"
+    When I run vagrant with `config --unset foo`
+    Then the "foo" setting should not be configured
+
+  Scenario: Running `vagrant config --all` prompts for each available setting
+    When I run vagrant with `config --all` interactively
+    And I enter the following at each prompt:
+      | git_user      | foo     |
+      | vagrant_ram   | 8096    |
+      | vagrant_cores | 8       |
+      | static_ip     | 1.1.1.1 |
+      | http_port     | 8888    |
+      | nfs_shares    | no      |
+      | forward_agent | yes     |
+      | forward_x11   | no      |
+    Then the command should have completed successfully
+    And the current settings should be:
+      | git_user      | foo     |
+      | vagrant_ram   | 8096    |
+      | vagrant_cores | 8       |
+      | static_ip     | 1.1.1.1 |
+      | http_port     | 8888    |
+      | nfs_shares    | no      |
+      | forward_agent | yes     |
+      | forward_x11   | no      |
+
+  Scenario: Running `vagrant config --required` prompts for only required 
settings
+    Given the "git_user" setting is not configured
+    When I run vagrant with `config --required` interactively
+    And I enter the following at each prompt:
+      | git_user | foo |
+    Then the command should have completed successfully
+    And the current settings should be:
+      | git_user | foo |
+
+  Scenario: Running `vagrant config --required` skips configured settings
+    Given the "git_user" setting is "foo"
+    When I run vagrant with `config --required` interactively
+    Then the command should have completed successfully
diff --git a/mediawiki-vagrant.gemspec b/mediawiki-vagrant.gemspec
index 865e6a6..a1cac4f 100644
--- a/mediawiki-vagrant.gemspec
+++ b/mediawiki-vagrant.gemspec
@@ -22,6 +22,6 @@
 
     s.require_paths = ['lib']
 
+    s.add_development_dependency 'aruba', '~> 0.6', '>= 0.6.2'
     s.add_development_dependency 'rspec', '~> 3.1', '>= 3.1.0'
-    s.add_development_dependency 'fakefs', '~> 0.6', '>= 0.6.5'
 end

-- 
To view, visit https://gerrit.wikimedia.org/r/190586
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I352267bb591f8de911a11072954f337ebbea89c7
Gerrit-PatchSet: 9
Gerrit-Project: mediawiki/vagrant
Gerrit-Branch: master
Gerrit-Owner: Dduvall <[email protected]>
Gerrit-Reviewer: BryanDavis <[email protected]>
Gerrit-Reviewer: Cmcmahon <[email protected]>
Gerrit-Reviewer: Dduvall <[email protected]>
Gerrit-Reviewer: Hashar <[email protected]>
Gerrit-Reviewer: Ori.livneh <[email protected]>
Gerrit-Reviewer: Zfilipin <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to