From 363ff19d6ce8e13a9f56ef001a68acd4380842d0 Mon Sep 17 00:00:00 2001 From: Hardy Ferentschik Date: Mon, 25 Apr 2016 14:43:26 +0200 Subject: [PATCH] Issue #195 Adding Cucumber and Aruba based acceptance tests - Adding required dependencies - Adding tests - Updating REDAME on how to run tests --- .config/cucumber.yml | 12 ++++ .gitignore | 15 ++++- Gemfile | 12 ++-- README.md | 105 ++++++++++++++++++++++---------- Rakefile | 96 ++++++++++++++++++++++++++++- features/box-command.feature | 38 ++++++++++++ features/env-command.feature | 44 +++++++++++++ features/help-command.feature | 72 ++++++++++++++++++++++ features/openshift.feature | 46 ++++++++++++++ features/status-command.feature | 24 ++++++++ features/support/env.rb | 49 +++++++++++++++ 11 files changed, 474 insertions(+), 39 deletions(-) create mode 100644 .config/cucumber.yml create mode 100644 features/box-command.feature create mode 100644 features/env-command.feature create mode 100644 features/help-command.feature create mode 100644 features/openshift.feature create mode 100644 features/status-command.feature create mode 100644 features/support/env.rb diff --git a/.config/cucumber.yml b/.config/cucumber.yml new file mode 100644 index 0000000..025a21b --- /dev/null +++ b/.config/cucumber.yml @@ -0,0 +1,12 @@ +# config/cucumber.yml +##YAML Template +--- +default: --profile html + +pretty: --format pretty +html: --format progress --format html --out=build/features_report.html + +help: --tags @help --profile html +box: --tags @box --profile html +env: --tags @env --profile html +openshift: --tags @openshift --profile html \ No newline at end of file diff --git a/.gitignore b/.gitignore index 9f0973e..590d436 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,17 @@ +# Ruby, Bundler Gemfile.lock -.vagrant .bundle +.ruby-version +.ruby-gemset + +# Vagrant +.vagrant + +# Idea +.idea +*.iml + +# Build and tmp directories +tmp +build pkg diff --git a/Gemfile b/Gemfile index 675e33f..07d478e 100644 --- a/Gemfile +++ b/Gemfile @@ -3,11 +3,15 @@ source 'https://rubygems.org' gemspec group :development do - gem 'vagrant', git: 'https://github.com/mitchellh/vagrant.git' - # added as the vagrant component wouldn't build without it - gem 'json' + gem 'vagrant', git: 'https://github.com/mitchellh/vagrant.git' gem 'rake' - gem 'bundler', '~> 1.6' + gem 'vagrant-libvirt' + gem 'fog-libvirt', '0.0.3' # https://github.com/pradels/vagrant-libvirt/issues/568 + gem 'mechanize' + gem 'json' + gem 'cucumber', '~> 2.1' + gem 'aruba', '~> 0.13' + gem 'komenda', '~> 0.1.6' end group :plugins do diff --git a/README.md b/README.md index b8e68c4..657fa42 100644 --- a/README.md +++ b/README.md @@ -1,34 +1,36 @@ # vagrant-service-manager -* [Objective](#objective) -* [Example Execution of the Plugin](#example_execution) -* [Available Commands](#commands) -* [Exit codes](#exit_codes) -* [IP Address Detection](#ip_addr) -* [Getting Involved with the Project](#Contributing) -* [Builds](#builds) + +- [Objective](#objective) +- [Usage](#usage) + - [Example execution of the plugin](#example-execution-of-the-plugin) + - [Available commands](#available-commands) + - [Exit codes](#exit-codes) + - [IP address detection](#ip-address-detection) +- [Development](#development) + - [Setup](#setup) + - [Acceptance tests](#acceptance-tests) + - [Builds](#builds) +- [Getting involved](#getting-involved) -The vagrant-service-manager plugin is designed to enable easier access to the features and services provided by the [Atomic Developer Bundle (ADB)](https://github.com/projectatomic/adb-atomic-developer-bundle). It provides setup information, including environment variables and certificates, required to access services provided by the ADB and is a must have for most ADB users. - -This plugin makes it easier to use the ADB with host-based tools such as Eclipse and the docker and kubernetes CLI commands. Details on how to use ADB with this plugin can be found in the [ADB Documentation](https://github.com/projectatomic/adb-atomic-developer-bundle/blob/master/docs/using.rst). - + -## Objective -The [ADB](https://github.com/projectatomic/adb-atomic-developer-bundle) provides a ready-to-use development environment for container applications. With ADB, developers can dive right into producing complex, multi-container applications. - -The vagrant-service-manager provides the user with: + +# Objective +The vagrant-service-manager plugin is designed to enable easier access to the features and services provided by the [Atomic Developer Bundle (ADB)](https://github.com/projectatomic/adb-atomic-developer-bundle). It provides setup information, including environment variables and certificates, required to access services provided by the ADB and is a must have for most ADB users. -* A CLI to configure the ADB for different use cases and to provide an interface between ADB and the user's development environment. -* A tool to control and configure the ADB from the -developer's workstation without having to `ssh` directly into the ADB virtual machine. +This plugin makes it easier to use the ADB with host-based tools such as Eclipse and the docker and kubernetes CLI commands. Details on how to use ADB with this plugin can be found in the [ADB Documentation](https://github.com/projectatomic/adb-atomic-developer-bundle/blob/master/docs/using.rst). + +# Usage -## Example Execution of the Plugin + +## Example execution of the plugin 1. Install vagrant-service-manager plugin: - + vagrant plugin install vagrant-service-manager 2. Download the relevant Vagrantfile for your [ADB](https://github.com/projectatomic/adb-atomic-developer-bundle) vagrant box, from the [repository](https://github.com/projectatomic/adb-atomic-developer-bundle/tree/master/components/centos). For further details on the usage of custom Vagrantfiles designed for specific use cases, refer to the [Usage Documentation](https://github.com/projectatomic/adb-atomic-developer-bundle/blob/master/docs/using.rst). @@ -39,7 +41,7 @@ developer's workstation without having to `ssh` directly into the ADB virtual ma 4. Run the plugin to get environment variables and certificates: - $ vagrant service-manager env docker + $ vagrant service-manager env docker # Set the following environment variables to enable access to the # docker daemon running inside of the vagrant virtual machine: export DOCKER_HOST=tcp://172.28.128.4:2376 @@ -52,7 +54,8 @@ developer's workstation without having to `ssh` directly into the ADB virtual ma **Note:** The required TLS certificates are copied to the host machine at the time of `vagrant up` itself. Every run of `vagrant service-manager env docker` checks for the validity of the certificates on the host machine by matching the certificates inside the box. If the certificates on the host machine are invalid, this command will also re-download the certificates onto the host machine. -## Available Commands + +## Available commands The following section lists the available commands for the plugin and their explanation: @@ -84,9 +87,8 @@ The following section lists the available commands for the plugin and their expl Displays the possible commands, options and other relevant information for the vagrant-service-manager plugin. If a `command` is specified, only the help relevant to that command is displayed. - - -## Exit codes + +## Exit codes The following table lists the plugin's exit codes and their meaning: @@ -98,23 +100,60 @@ Exit Code Number | Meaning `126` | A service inside the box is not running / Command invoked cannot execute -## IP Address Detection + +## IP address detection There is no standardized way of detecting Vagrant box IP addresses. This code uses the last IPv4 address available from the set of configured addresses that are *up*. i.e. if eth0, eth1, and eth2 are all up and have IPv4 addresses, the address on eth2 is used. -## Getting Involved with the Project + +# Development -We welcome your input. You can submit issues or pull requests with respect to the vagrant-service-manager plugin. Refer to the [contributing guidelines](https://github.com/projectatomic/vagrant-service-manager/blob/master/CONTRIBUTING.md) for detailed information on how to contribute to this plugin. + +## Setup -You can contact us on: - * IRC: #atomic and #nulecule on freenode - * Mailing List: container-tools@redhat.com +After cloing the repository, install the [Bundler](http://bundler.io/) gem: + $ gem install bundler -## Builds +Then setup your project dependencies: -- Gem: https://rubygems.org/gems/vagrant-service-manager + $ bundle install + +The build is driven via rake. All build related tash should be executed in the +Bundler environment, e.g. `bundle exec rake clean`. You can get a list of available +Rake tasks via: + $ bundle exec rake -T + + +## Acceptance tests + +The source contains also a set of [Cucumber](https://cucumber.io/) acceptance tests. They can be run via: + + $ bundle exec rake features + +The tests assume that the ADB and CDK box files are available under +_build/boxes/adb-\.box_ resp _build/boxes/cdk-\.box_. You can +either copy the box files manually or use the _get_adk_ resp. _get_cdk_ Rake tasks. + +After test execution the Cucumber test reports can be found under _build/features_report.html_ + + +## Builds + +- Gem: https://rubygems.org/gems/vagrant-service-manager - Copr build: https://copr.fedorainfracloud.org/coprs/nshaikh/vagrant-service-manager/builds/ + + +# Getting involved + +We welcome your input. You can submit issues or pull requests with respect to +the vagrant-service-manager plugin. Refer to the +[contributing guidelines](https://github.com/projectatomic/vagrant-service-manager/blob/master/CONTRIBUTING.md) +for detailed information on how to contribute to this plugin. + +You can contact us on: + * IRC: #atomic and #nulecule on freenode + * Mailing List: container-tools@redhat.com diff --git a/Rakefile b/Rakefile index 2995527..7e6de04 100644 --- a/Rakefile +++ b/Rakefile @@ -1 +1,95 @@ -require "bundler/gem_tasks" +require 'bundler/gem_tasks' +require 'rake/clean' +require 'cucumber/rake/task' +require 'mechanize' +require 'fileutils' +require 'yaml' + +CDK_DOWNLOAD_URL='https://access.redhat.com/downloads/content/293/ver=2/rhel---7/2.0.0/x86_64/product-software' +CDK_BOX_BASE_NAME='rhel-cdk-kubernetes-7.2-23.x86_64.vagrant' + +ADB_DOWNLOAD_URL='http://cloud.centos.org/centos/7/atomic/images' +ADB_BOX_BASE_NAME='AtomicDeveloperBundle-2.0.0-CentOS7' + +CLOBBER.include('pkg') +CLEAN.include('build') + +Cucumber::Rake::Task.new(:features) + +namespace :features do + cucumber_config = YAML.load_file('./.config/cucumber.yml') + cucumber_config.each_key do |key| + if key == 'default' + next + end + Cucumber::Rake::Task.new(key.to_sym, "Run Cucumber features using profile '#{key}' (see cucumber.yml)'") do |t| + t.profile = key + end + end +end + +desc 'Download CDK Vagrant box using the specified provider (default \'virtualbox\')' +task :get_cdk, [:provider] do |t, args| + if args[:provider].nil? + provider='virtualbox' + else + provider=args[:provider] + end + agent = Mechanize.new + agent.follow_meta_refresh = true + agent.get(CDK_DOWNLOAD_URL) do |page| + + # Submit first form which is the redirect to login page form + login_page = page.forms.first.submit + + # Submit the login form + after_login = login_page.form_with(:name => 'login_form') do |f| + username_field = f.field_with(:id => 'username') + username_field.value = 'service-manager@mailinator.com' + password_field = f.field_with(:id => 'password') + password_field.value = 'service-manager' + end.click_button + + # There is one more redirect after successful login + download_page = after_login.forms.first.submit + + download_page.links.each do |link| + if link.href =~ /#{Regexp.quote(CDK_BOX_BASE_NAME)}-#{Regexp.quote(provider)}.box/ + download_dir = File.join(File.dirname(__FILE__), 'build', 'boxes') + unless File.directory?(download_dir) + FileUtils.mkdir_p(download_dir) + end + agent.pluggable_parser.default = Mechanize::Download + puts "Downloading #{link.href}" + agent.get(link.href).save(File.join(download_dir, "cdk-#{provider}.box")) + end + end + end +end + +desc 'Download ADB Vagrant box using the specified provider (default \'virtualbox\')' +task :get_adb, [:provider] do |t, args| + if args[:provider].nil? + provider='virtualbox' + else + provider=args[:provider] + end + agent = Mechanize.new + agent.follow_meta_refresh = true + agent.get(ADB_DOWNLOAD_URL) do |page| + page.links.each do |link| + if match = link.href.match(/#{Regexp.quote(ADB_BOX_BASE_NAME)}-(.*).box/) + if match.captures[0].downcase == provider + download_dir = File.join(File.dirname(__FILE__), 'build', 'boxes') + unless File.directory?(download_dir) + FileUtils.mkdir_p(download_dir) + end + agent.pluggable_parser.default = Mechanize::Download + puts "Downloading #{ADB_DOWNLOAD_URL}/#{link.href}" + agent.get(link.href).save(File.join(download_dir, "adb-#{provider}.box")) + end + end + end + end +end + diff --git a/features/box-command.feature b/features/box-command.feature new file mode 100644 index 0000000..c4c3717 --- /dev/null +++ b/features/box-command.feature @@ -0,0 +1,38 @@ +Feature: Command output from box command + service-manager should return the correct output from box commands + + @box + Scenario Outline: Boot and execute box commands + Given a file named "Vagrantfile" with: + """ + Vagrant.configure('2') do |config| + config.vm.box = '' + config.vm.box_url = '-.box' + config.vm.network :private_network, ip: '10.10.10.123' + config.servicemanager.services = 'docker' + end + """ + + When I successfully run `bundle exec vagrant up --provider ` + And I run `bundle exec vagrant service-manager box` + Then the exit status should be 1 + And stdout from "bundle exec vagrant service-manager box" should contain: + """ + Usage: vagrant service-manager box [options] + + Sub-Command: + version display version and release information about the running VM + ip display routable IP address of the running VM + + Options: + --script-readable display information in a script readable format + -h, --help print this help + """ + + When I successfully run `bundle exec vagrant service-manager box ip` + Then stdout from "bundle exec vagrant service-manager box ip" should contain "10.10.10.123" + + Examples: + | box | provider | baseurl | + | cdk | virtualbox | file://../boxes/cdk | + | adb | virtualbox | file://../boxes/adb | \ No newline at end of file diff --git a/features/env-command.feature b/features/env-command.feature new file mode 100644 index 0000000..2c8676f --- /dev/null +++ b/features/env-command.feature @@ -0,0 +1,44 @@ +Feature: Command output from env command + service-manager should return the correct output from env commands + + @env + Scenario Outline: Boot and execute env commands + Given a file named "Vagrantfile" with: + """ + Vagrant.configure('2') do |config| + config.vm.box = '' + config.vm.box_url = '-.box' + config.vm.network :private_network, ip: '10.10.10.123' + config.servicemanager.services = 'docker' + end + """ + + When I successfully run `bundle exec vagrant up --provider ` + And I successfully run `bundle exec vagrant service-manager env` + Then stdout from "bundle exec vagrant service-manager env" should be evaluable in a shell + + When I successfully run `bundle exec vagrant service-manager env --script-readable` + Then stdout from "bundle exec vagrant service-manager env --script-readable" should be script readable + + When I successfully run `bundle exec vagrant service-manager env docker` + Then stdout from "bundle exec vagrant service-manager env docker" should be evaluable in a shell + And stdout from "bundle exec vagrant service-manager env docker" should contain "export DOCKER_HOST=tcp://10.10.10.123:2376" + And stdout from "bundle exec vagrant service-manager env docker" should match /export DOCKER_CERT_PATH=.*\/.vagrant\/machines\/cdk\/virtualbox\/docker/ + And stdout from "bundle exec vagrant service-manager env docker" should contain "export DOCKER_TLS_VERIFY=1" + And stdout from "bundle exec vagrant service-manager env docker" should contain "export DOCKER_API_VERSION=1.21" + And stdout from "bundle exec vagrant service-manager env docker" should match /# eval "\$\(vagrant service-manager env docker\)"/ + + When I successfully run `bundle exec vagrant service-manager env docker --script-readable` + Then stdout from "bundle exec vagrant service-manager env docker --script-readable" should be script readable + + When I run `bundle exec vagrant service-manager env openshift` + Then the exit status should be 126 + And stderr from "bundle exec vagrant service-manager env openshift" should contain: + """ + # OpenShift service is not running in the vagrant box. + """ + + Examples: + | box | provider | baseurl | + | cdk | virtualbox | file://../boxes/cdk | + | adb | virtualbox | file://../boxes/adb | \ No newline at end of file diff --git a/features/help-command.feature b/features/help-command.feature new file mode 100644 index 0000000..7ff0cb3 --- /dev/null +++ b/features/help-command.feature @@ -0,0 +1,72 @@ +Feature: Command output from help command + service-manager should return the correct output from its help commands + + @help + Scenario Outline: Boot and execute help commands + Given a file named "Vagrantfile" with: + """ + Vagrant.configure('2') do |config| + config.vm.box = '' + config.vm.box_url = '-.box' + config.vm.network :private_network, ip: '10.10.10.123' + config.servicemanager.services = 'docker' + end + """ + + When I successfully run `bundle exec vagrant up --provider ` + And I successfully run `bundle exec vagrant service-manager --help` + Then stdout from "bundle exec vagrant service-manager --help" should contain: + """ + Usage: vagrant service-manager [options] + + Commands: + env displays connection information for services in the box + box displays box related information like version, release, IP etc + restart restarts the given systemd service in the box + status list services and their running state + + Options: + -h, --help print this help + + For help on any individual command run `vagrant service-manager COMMAND -h` + """ + + When I successfully run `bundle exec vagrant service-manager -h` + Then stdout from "bundle exec vagrant service-manager -h" should contain: + """ + Usage: vagrant service-manager [options] + + Commands: + env displays connection information for services in the box + box displays box related information like version, release, IP etc + restart restarts the given systemd service in the box + status list services and their running state + + Options: + -h, --help print this help + + For help on any individual command run `vagrant service-manager COMMAND -h` + """ + + When I run `bundle exec vagrant service-manager` + Then the exit status should be 1 + And stdout from "bundle exec vagrant service-manager -h" should contain: + """ + Usage: vagrant service-manager [options] + + Commands: + env displays connection information for services in the box + box displays box related information like version, release, IP etc + restart restarts the given systemd service in the box + status list services and their running state + + Options: + -h, --help print this help + + For help on any individual command run `vagrant service-manager COMMAND -h` + """ + + Examples: + | box | provider | baseurl | + | cdk | virtualbox | file://../boxes/cdk | + | adb | virtualbox | file://../boxes/adb | \ No newline at end of file diff --git a/features/openshift.feature b/features/openshift.feature new file mode 100644 index 0000000..05d135d --- /dev/null +++ b/features/openshift.feature @@ -0,0 +1,46 @@ +Feature: Command output from various OpenShift related commands + service-manager should return the correct output from commands affecting OpenShift + + @openshift + Scenario Outline: Boot and execute commands + Given a file named "Vagrantfile" with: + """ + Vagrant.configure('2') do |config| + config.vm.box = '' + config.vm.box_url = '-.box' + config.vm.network :private_network, ip: '10.10.10.123' + config.servicemanager.services = 'docker' + config.vm.provision "shell", inline: <<-SHELL + systemctl enable openshift 2>&1 + systemctl start openshift | true + SHELL + end + """ + + When I successfully run `bundle exec vagrant up --provider ` + # TODO, for some reason I can not use 'successfully' here. Seems the exit code is not 0 in this case!? + And I run `bundle exec vagrant service-manager env openshift` + Then stdout from "bundle exec vagrant service-manager env openshift" should be evaluable in a shell + And stdout from "bundle exec vagrant service-manager env openshift" should contain: + """ + # You can access the OpenShift console on: https://10.10.10.123:8443/console + # To use OpenShift CLI, run: oc login https://10.10.10.123:8443 + export OPENSHIFT_URL=https://10.10.10.123:8443 + export OPENSHIFT_WEB_CONSOLE=https://10.10.10.123:8443/console + + # run following command to configure your shell: + # eval "$(vagrant service-manager env openshift)" + """ + + When I successfully run `bundle exec vagrant service-manager env openshift --script-readable` + Then stdout from "bundle exec vagrant service-manager env openshift --script-readable" should be script readable + And stdout from "bundle exec vagrant service-manager env openshift --script-readable" should contain: + """ + OPENSHIFT_URL=https://10.10.10.123:8443 + OPENSHIFT_WEB_CONSOLE=https://10.10.10.123:8443/console + """ + + Examples: + | box | provider | baseurl | + | cdk | virtualbox | file://../boxes/cdk | + #| adb | virtualbox | file://../boxes/adb | \ No newline at end of file diff --git a/features/status-command.feature b/features/status-command.feature new file mode 100644 index 0000000..9c0aeb7 --- /dev/null +++ b/features/status-command.feature @@ -0,0 +1,24 @@ +Feature: Command output from status command + service-manager should return the correct output from status command + + @status + Scenario Outline: Boot and execute status command + Given a file named "Vagrantfile" with: + """ + Vagrant.configure('2') do |config| + config.vm.box = '' + config.vm.box_url = '-.box' + config.vm.network :private_network, ip: '10.10.10.123' + config.servicemanager.services = 'docker' + end + """ + + When I successfully run `bundle exec vagrant up --provider ` + And I successfully run `bundle exec vagrant service-manager status` + Then stdout from "bundle exec vagrant service-manager status" should contain "docker - running" + Then stdout from "bundle exec vagrant service-manager status" should contain "openshift - stopped" + + Examples: + | box | provider | baseurl | + | cdk | virtualbox | file://../boxes/cdk | + | adb | virtualbox | file://../boxes/adb | \ No newline at end of file diff --git a/features/support/env.rb b/features/support/env.rb new file mode 100644 index 0000000..f50e31b --- /dev/null +++ b/features/support/env.rb @@ -0,0 +1,49 @@ +require 'aruba/cucumber' +require 'komenda' + +Aruba.configure do |config| + config.exit_timeout = 300 + config.activate_announcer_on_command_failure = [:stdout, :stderr] + config.working_directory = 'build/aruba' +end + +After do |_scenario| + if File.exist?(File.join(aruba.config.working_directory, 'Vagrantfile')) + Komenda.run('bundle exec vagrant destroy -f', cwd: aruba.config.working_directory, fail_on_fail: true) + end +end + +############################################################################### +# Some helper functions +############################################################################### +# When running Vagrant from within a plugin development environment, Vagrant +# prints a warning which we can ignore +def stdout_without_plugin_context(raw_stdout) + raw_stdout.lines.to_a[6..-1].join +end + +def output_is_evaluable(raw_stdout) + console_out = stdout_without_plugin_context(raw_stdout) + console_out.each_line do |line| + expect(line).to match(/^#.*|^export [a-zA-Z_]+=.*|^\n/) + end +end + +def output_is_script_readable(raw_stdout) + console_out = stdout_without_plugin_context(raw_stdout) + console_out.each_line do |line| + expect(line).to match(/^[a-zA-Z_]+=.*$/) + end +end + +Then(/^stdout from "([^"]*)" should be evaluable in a shell$/) do |cmd| + output_is_evaluable(aruba.command_monitor.find(Aruba.platform.detect_ruby(cmd)).send(:stdout)) +end + +Then(/^stdout from "([^"]*)" should be script readable$/) do |cmd| + output_is_script_readable(aruba.command_monitor.find(Aruba.platform.detect_ruby(cmd)).send(:stdout)) +end + +Then(/^stdout from "([^"]*)" should match \/(.*)\/$/) do |cmd, regexp| + aruba.command_monitor.find(Aruba.platform.detect_ruby(cmd)).send(:stdout) =~ /#{regexp}/ +end \ No newline at end of file