Skip to content
This repository has been archived by the owner on Jul 29, 2018. It is now read-only.

Fix #195: Acceptance tests based on Cucumber #205

Merged
merged 1 commit into from
May 13, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .config/cucumber.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# config/cucumber.yml
##YAML Template
---
default: --profile html

pretty: --format pretty -b
html: --format progress --format html --out=build/features_report.html -b

help: --tags @help --profile html
box: --tags @box --profile html
env: --tags @env --profile html
openshift: --tags @openshift --profile html
15 changes: 14 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -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
13 changes: 9 additions & 4 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,16 @@ 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'
gem 'launchy'
end

group :plugins do
Expand Down
149 changes: 105 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,42 +1,45 @@
# vagrant-service-manager

* [Objective](#objective)
* [How to Install the Plugin](#installation)
* [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)


<!-- MarkdownTOC -->

- [Objective](#objective)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bexelbie @Preeticp Please have a look at this new TOC with nested feature.

- [Installation](#installation)
- [Installing from a RubyGems](#installing-from-a-rubygems)
- [Installing from RPM](#installing-from-rpm)
- [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)
- [Getting involved](#getting-involved)

<!-- /MarkdownTOC -->


<a name="objective"></a>
# 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.

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 <a name="objective"></a>

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:

* 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.


## How to Install the Plugin <a name="installation"></a>
<a name="installation"></a>
# Installation

The plugin is distributed as both a Ruby Gem and via RPM using the Fedora COPR system.

### Installing from a Ruby Gem
<a name="installing-from-a-rubygems"></a>
## Installing from a RubyGems

The [Ruby Gem](https://rubygems.org/gems/vagrant-service-manager) is
available via the standard vagrant installation method:
The vagrant-service-manager [gem](https://rubygems.org/gems/vagrant-service-manager) is available on [RubyGems](https://rubygems.org) and can be installed via the
standard Vagrant plugin installation method:

$ vagrant plugin install vagrant-service-manager

### Installing from RPM
<a name="installing-from-rpm"></a>
## Installing from RPM

The [Copr
build](https://copr.fedorainfracloud.org/coprs/nshaikh/vagrant-service-manager/builds/)
Expand All @@ -45,21 +48,25 @@ is accessible via the standard COPR access/install method:
$ dnf copr enable nshaikh/vagrant-service-manager
$ dnf --enablerepo=nshaikh-vagrant-service-manager install vagrant-service-manager

## Example Execution of the Plugin <a name="example_execution"></a>
<a name="usage"></a>
# Usage

<a name="example-execution-of-the-plugin"></a>
## 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).

3. Start the ADB vagrant box using `vagrant up`. For detailed instructions consult the [Installation Documentation](https://github.com/projectatomic/adb-atomic-developer-bundle/blob/master/docs/installing.rst).

**Note:** When the vagrant-service-manager plugin is loaded and a box is started using the VirtualBox provider, the user needs to add a routable non NAT network interface declaration in the Vagrantfile. If the user does not provide a network declaration in the Vagrantfile, a private DHCP network is added by default and a warning is displayed.
**Note:** When the vagrant-service-manager plugin is loaded and a box is started using the VirtualBox provider, the user needs to add a routable non NAT network interface declaration in the Vagrantfile. If the user does not provide a network declaration in the Vagrantfile, a private DHCP network is added by default and a warning is displayed.

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
Expand All @@ -69,44 +76,44 @@ is accessible via the standard COPR access/install method:
# run following command to configure your shell:
# eval "$(vagrant service-manager env docker)"

**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.
**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 <a name="commands"></a>
<a name="available-commands"></a>
## Available commands

The following section lists the available commands for the plugin and their explanation:

1. `vagrant service-manager env [service] [--script-readable]`
1. `vagrant service-manager env [service] [--script-readable]`

Displays connection information for all active services in the box in a manner that can be evaluated in a shell. If a `service` is specified, only the information for that service is displayed. When `--script-readable` is specified the output is in `key=value` format. The supported services are: Docker; OpenShift.

2. `vagrant service-manager box [command]`

Displays box related information like release version, IP etc.
Displays box related information like release version, IP etc.

3. `vagrant service-manager box version [--script-readable]`

Displays the version and release information of the running VM. When `--script-readable` is specified the output is in `key=value` format.

4. `vagrant service-manager box ip`
4. `vagrant service-manager box ip`

Displays the routable IP address of the running VM.
Displays the routable IP address of the running VM.

5. `vagrant service-manager status [service]`
5. `vagrant service-manager status [service]`

Lists services and their running state. If a `service` is specified only the status of that service is displayed. If no service is provided then only supported orchestrators are reported.

6. `vagrant service-manager restart [service]`
6. `vagrant service-manager restart [service]`

Restarts the given service in the box.

7. `vagrant service-manager [command] [--help | -h]`

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 <a name="exit_codes"></a>
<a name="exit-codes"></a>
## Exit codes

The following table lists the plugin's exit codes and their meaning:

Expand All @@ -118,15 +125,69 @@ Exit Code Number | Meaning
`126` | A service inside the box is not running / Command invoked cannot execute


## IP Address Detection <a name="ip_addr"></a>
<a name="ip-address-detection"></a>
## 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 <a name="Contributing"></a>
<a name="development"></a>
# Development

<a name="setup"></a>
## Setup

After cloning the repository, install the [Bundler](http://bundler.io/) gem:

$ gem install bundler

Then setup your project dependencies:

$ 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

<a name="acceptance-tests"></a>
## Acceptance tests
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think Acceptance Tests would be more appropriate here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why? You mean a capital 'T'? I don't think so?


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-\<provider\>.box_ resp _build/boxes/cdk-\<provider\>.box_. You can
either copy the box files manually or use the _get_adb_ resp. _get_cdk_ Rake tasks.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a way where I can use aleady installed Vagrant box for the tests? For example I should be able able to use config.vm.box = "projectatomic/adb"

Copy link
Collaborator

@LalatenduMohanty LalatenduMohanty May 13, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will save some internet bandwidth for me as I dont have to re-download box again which is already on the workstation i.e Fedora. I had downloaded the box using following commands

vagrant init projectatomic/adb
vagrant up

The Vagrant box is kept inside /home/lmohanty/.vagrant.d/boxes/projectatomic-VAGRANTSLASH-adb/2.0.0 extracted format i.e

[lmohanty@LalatenduM-laptop 2.0.0]$ pwd
/home/lmohanty/.vagrant.d/boxes/projectatomic-VAGRANTSLASH-adb/2.0.0

[lmohanty@LalatenduM-laptop 2.0.0]$ tree ./
./
└── libvirt
    ├── box.img
    ├── metadata.json
    └── Vagrantfile

1 directory, 3 files

Copy link
Contributor

@coolbrg coolbrg May 13, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@LalatenduMohanty you can convert that into .box file using Vagrant package command.

It goes like this:

1. mkdir tmp_adb
2. vagrant init projectatomic/adb
3. vagrant up
4. vagrant package --vagrantfile Vagrantfile --output ~/Downloads/adb-virtualbox.box

My first attempt was through those local boxes but it seems that those are corrupt(fpaste here).

We can create an issue to figure that out.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But why we cant just reuse the installed box? I do not think repackaging the Vagrant box with vagrant package --vagrantfile Vagrantfile --output ~/Downloads/adb-virtualbox.box is a good idea.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's why I added at the bottom that we can figure it out later all possible options 😄 .

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like the actually adds the box, un-compresses the box file , hence the issue

Per default only the scenarios for ADB in combination with the VirtualBox provider are run. However, you can
also run against CDK and/or use the Libvirt provider using the environment variables _BOX_ resp _PROVIDER_:

# Run tests against CDK using Libvirt
$ bundle exec rake features BOX=cdk PROVIDER=libvirt

# Run against ADB and CDK (boxes are comma seperated)
$ bundle exec rake features BOX=cdk,adb

You can also run a single feature specifying the explicit feature file to use:

$ bundle exec rake features FEATURE=features/<feature-filename>.feature
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍


After test execution the Cucumber test reports can be found under _build/features_report.html_.
They can also be opened via

$ bundle exec rake features:open_report
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

your wish is my command :-)


<a name="getting-involved"></a>
# 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.
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
Expand Down
92 changes: 91 additions & 1 deletion Rakefile
Original file line number Diff line number Diff line change
@@ -1 +1,91 @@
require "bundler/gem_tasks"
require 'bundler/gem_tasks'
require 'rake/clean'
require 'cucumber/rake/task'
require 'mechanize'
require 'fileutils'
require 'yaml'
require 'launchy'

CDK_DOWNLOAD_URL='https://access.redhat.com/downloads/content/293/ver=2/rhel---7/2.0.0/x86_64/product-software'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably better to extract these links in separate file says constants in order to reduce Rakefile size.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-1 I don't think the Rakefile size is an issue for now. The more files the more files the harder it becomes to piece everything together.

A valid argument might be to extract this into some sort of properties file to be able to change these settings w/o affecting the Rakefile, but I don't think it is worth the effort here. I would suggest we wait and see how this shapes up.

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')

task :init do
FileUtils.mkdir_p 'build'
puts ENV['FOO']
end

# Cucumber acceptance test tasks
Cucumber::Rake::Task.new(:features)
task :features => :init

namespace :features do
desc 'Opens the HTML Cucumber test report'
task :open_report do
Launchy.open('./build/features_report.html')
end
end

desc 'Download CDK Vagrant box using the specified provider (default \'virtualbox\')'
task :get_cdk, [:provider] do |t, args|
provider = args[:provider].nil? ? 'virtualbox' : args[:provider]
agent = Mechanize.new
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to take out these lower level operations in separate file and then call it here.

Adding these code here actually make the Rakefile bulky and would be difficult to read it as a whole when it scales up.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So where do you see it scaling to? I don't consider 92 lines of Rakefile as bulky and I am not su sure whether it will grow so much.

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'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it a real email ID?

Copy link
Contributor

@coolbrg coolbrg May 11, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its a disposable email id provided by https://mailinator.com/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. Avoids to pass anything in via environment variables. Works out of the box.

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
task :get_cdk => :init

desc 'Download ADB Vagrant box using the specified provider (default \'virtualbox\')'
task :get_adb, [:provider] do |t, args|
provider = args[:provider].nil? ? 'virtualbox' : args[:provider]
agent = Mechanize.new
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
task :get_adb => :init
Loading