leibniz 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -15,3 +15,4 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ .idea/
data/Gemfile CHANGED
@@ -1,4 +1,7 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
+ #ruby=ruby-2.0.0
4
+ #ruby-gemset=leibniz
5
+
3
6
  # Specify your gem's dependencies in leibniz.gemspec
4
7
  gemspec
data/README.md CHANGED
@@ -1,6 +1,9 @@
1
1
  # Leibniz
2
2
 
3
- Leibniz is an integration testing tool aimed at the Chef community.
3
+ Leibniz is simple utility which provides the ability to launch
4
+ infrastructure using Test Kitchen, and run acceptance tests against
5
+ that infrastructure. It is designed to be used as part of a set of
6
+ Cucumber / Gherkin features.
4
7
 
5
8
  ## Installation
6
9
 
@@ -18,7 +21,246 @@ Or install it yourself as:
18
21
 
19
22
  ## Usage
20
23
 
21
- TODO: Write usage instructions here
24
+ ### The Leibniz CLI
25
+
26
+ Since version 0.2.0, Leibniz provides a basic CLI which will create and populate an example Cucumber feature to get you started. You can call this using:
27
+
28
+ leibniz init
29
+
30
+ ### Getting Started
31
+
32
+ Leibniz takes the view that acceptance testing of infrastructure
33
+ should be performed from the outside in, and make assertions from the
34
+ perspective of an external user consuming the delivered
35
+ infrastructure.
36
+
37
+ To get started, you will need to write some features and some steps.
38
+ Depending on how you build your infrastructure (at present the assumed
39
+ approach is Berkshelf and wrapper cookbooks, but there's no reason why
40
+ it wouldn't work with Librarian-chef, or some other approach).
41
+
42
+ #### Using Berkshelf
43
+
44
+ Assuming you have Berkshelf installed, you can use the in-built
45
+ cookbook generator to create your wrapper cookbook. The alternative
46
+ is to create a cookbook directory, or use knife to create a cookbook,
47
+ and then add 'berkshelf' to a Gemfile, and run bundle install, followed by berks init.
48
+
49
+ Either way, once you have a cookbook which has been 'berksified' you
50
+ will have something that looks like this:
51
+
52
+ ```
53
+ .
54
+ ├── Berksfile
55
+ ├── Gemfile
56
+ ├── LICENSE
57
+ ├── README.md
58
+ ├── Thorfile
59
+ ├── Vagrantfile
60
+ ├── attributes
61
+ ├── chefignore
62
+ ├── definitions
63
+ ├── files
64
+ │   └── default
65
+ ├── libraries
66
+ ├── metadata.rb
67
+ ├── providers
68
+ ├── recipes
69
+ │   └── default.rb
70
+ ├── resources
71
+ └── templates
72
+ └── default
73
+ ```
74
+
75
+ #### Writing your first feature
76
+
77
+ We are going to take you through the process of iterating on the creation of a feature and its step definitions. In reality you might merge some of these steps together and not run cucumber as often as we do here, but this illustrates every step in the process.
78
+
79
+ First we need to create a directory to contain our features, then write our first feature:
80
+
81
+ ```
82
+ mkdir features
83
+ cd features
84
+ vi generic_webpage.feature
85
+ ```
86
+
87
+ The feature you write needs to have a `Background` section like this:
88
+
89
+ ```
90
+ Background:
91
+
92
+ Given I have provisioned the following infrastructure:
93
+ | Server Name | Operating System | Version | Chef Version | Run List |
94
+ | generic_webpage | ubuntu | 12.04 | 11.8.0 | generic_webpage::default |
95
+ And I have run Chef
96
+ ```
97
+
98
+ This background section is responsible for provisioning infrastructure and getting it into a state whereupon we can run some acceptance tests against it. The title of each column is defined by Leibiniz:
99
+
100
+ - `Server Name` - this is the name of the machine you will be provisioning. Leibniz will prepend `leibniz` to the name and will launch a machine with this name.
101
+ - `Operating System` - this translates to the base OS of a Vagrant box which is downloaded on demand. The boxes used are Opscode's 'Bento' boxes, and have nothing other than a base OS installed. At present `ubuntu`, `debian`, `centos` and `fedora` are supported.
102
+ - `Version` - this is version of the Operating System. See the Bento website for an up-to-date specification of the available versions.
103
+ - `Chef Version` - this is the version of the Chef 'client' software to be installed.
104
+ - `Run List` - this is the Chef run list which will be used when the node is converged.
105
+
106
+ These two steps are satisfied by Leibniz. We need to ensure the Leibniz library is available to Chef. To do this, add `leibniz` to your Gemfile, and run `bundle install`. Then create a `support` directory under your `features` directory, and within the `support` directory, create an `env.rb` file. This should read:
107
+
108
+ ```
109
+ require 'leibniz'
110
+ ```
111
+
112
+ Now create your step definitions:
113
+
114
+ ```
115
+ mkdir features/step_definitions
116
+ vi features/step_definitions/generic_webpage_steps.rb
117
+ ```
118
+
119
+ The following steps will build and converge the infrastructure described in the table:
120
+
121
+ ```
122
+ Given(/^I have provisioned the following infrastructure:$/) do |specification|
123
+ @infrastructure = Leibniz.build(specification)
124
+ end
125
+
126
+ Given(/^I have run Chef$/) do
127
+ @infrastructure.destroy
128
+ @infrastructure.converge
129
+ end
130
+ ```
131
+
132
+ At present, Leibniz only knows how to provision infrastructure using
133
+ the Vagrant driver. By default this will assume you have Virtualbox
134
+ on the system where you are running Cucumber. A top priority is to
135
+ support other Kitchen drivers, which will enable infrastructure to be
136
+ provisioned on cloud platforms, via LXC or Docker, or just with
137
+ Vagrant.
138
+
139
+ Once you have your feature, env.rb and steps in place, you can run
140
+ `cucumber`. This will build the infrastructure you described using
141
+ Chef.
142
+
143
+ You may find it useful to tail the logs during this process:
144
+
145
+ ```
146
+ tail -f .kitchen/logs/leibniz-generic-webpage.log
147
+ ```
148
+
149
+ If all goes well, you should see something like:
150
+
151
+ ```
152
+ Feature: Serve a generic webpage
153
+
154
+ In order to demonstrate how Leibniz works
155
+ As an infrastructure developer
156
+ I want to be able to serve a generic webpage and test it
157
+
158
+ Background: # features/crap_webpage.feature:7
159
+ Given I have provisioned the following infrastructure: # features/step_definitions/generic_webpage_steps.rb:1
160
+ | Server Name | Operating System | Version | Chef Version | Run List |
161
+ | generic_webpage | ubuntu | 12.04 | 11.8.0 | generic_webpage::default |
162
+ Using generic_webpage (0.1.0) from metadata
163
+ And I have run Chef # features/step_definitions/generic_webpage_steps.rb:5
164
+
165
+ 0 scenarios
166
+ 2 steps (2 passed)
167
+ 0m58.613s
168
+ ```
169
+
170
+ At this stage we have only provisioned the machine per the table we provided in the feature. We now need to describe an example of what the infrastructure does. Open the feature and add an example:
171
+
172
+ ```
173
+ Scenario: Infrastructure developer can see generic webpage
174
+ Given a URL "http://generic-webpage.com"
175
+ When I browse to the URL
176
+ Then I should see "This is a generic webpage"
177
+ ```
178
+
179
+ When we run cucumber again, we should be told that our steps are undefined. Cucumber will suggest some snippets we can use:
180
+
181
+ ```
182
+ You can implement step definitions for undefined steps with these snippets:
183
+
184
+ Given(/^a URL "(.*?)"$/) do |arg1|
185
+ pending # express the regexp above with the code you wish you had
186
+ end
187
+
188
+ When(/^I browse to the URL$/) do
189
+ pending # express the regexp above with the code you wish you had
190
+ end
191
+
192
+ Then(/^I should see "(.*?)"$/) do |arg1|
193
+ pending # express the regexp above with the code you wish you had
194
+ end
195
+ ```
196
+ Copy and paste these into `features/step_definitions/generic_webpage_steps.rb`, then run cucumber again. We should now see that the step runs, but is marked as pending - that is we haven't implemented the acceptance test.
197
+
198
+ The idea of Leibniz is to make the provisioning and converging of infrastructure nodes as painless and flexible as possible, enabling the infrastructure developer to dive into writing the acceptance tests right away. Future versions of the library may ship some useful features to help with common acceptance test types.
199
+
200
+ We now need to write the implementation of our acceptance tests:
201
+
202
+ - Given a URL "http://generic-webpage.com"
203
+ - When I browse to the URL
204
+ - Then I should see "This is a generic webpage"
205
+
206
+ The first step simply requires us to capture a host header that we can use as part of an http client:
207
+
208
+ ```
209
+ Given(/^a URL "(.*?)"$/) do |url|
210
+ @host_header = url.split("/").last
211
+ end
212
+ ```
213
+
214
+ The second step requires us to use an http client. There are many options available for this, Faraday is a simple one:
215
+
216
+ ```
217
+ When(/^I browse to the URL$/) do
218
+ connection = Faraday.new(url: "http://#{@infrastructure['generic-webpage'].ip}", headers: { 'Host' => @host_header }) do |faraday|
219
+ faraday.adapter Faraday.default_adapter
220
+ end
221
+ @page = connection.get('/').body
222
+ end
223
+ ```
224
+
225
+ Note: the ip of the infrastructure we have built is available as part of the @infrastructure object returned by Leibniz.
226
+
227
+ The final step is a simple rspec expectation:
228
+
229
+ ```
230
+ Then(/^I should see "(.*?)"$/) do |content|
231
+ expect (@page).to match /#{content}/
232
+ end
233
+ ```
234
+
235
+ When we run cucumber this time, the tests will fail because we've not implemented anything to actually serve a website, nor have we deployed the website for the web server to serve.
236
+
237
+ Making the tests pass (i.e. writing the Chef code to deploy a web server and serve a static web page) is left as an exercise for the reader. One the code is written, running cucumber again will converge the node and run the acceptance tests, resulting in the tests passing, like this:
238
+
239
+ ```
240
+ Feature: Serve a generic webpage
241
+
242
+ In order to demonstrate how Leibniz works
243
+ As an infrastructure developer
244
+ I want to be able to serve a generic webpage and test it
245
+
246
+ Background: # features/generic_webpage.feature:7
247
+ Given I have provisioned the following infrastructure: # features/step_definitions/generic_webpage_steps.rb:3
248
+ | Server Name | Operating System | Version | Chef Version | Run List |
249
+ | generic_webpage | ubuntu | 12.04 | 11.8.0 | generic_webpage::default |
250
+ Using generic_webpage (0.1.0)
251
+ Using apt (2.3.0)
252
+ Using apache2 (1.8.4)
253
+ And I have run Chef # features/step_definitions/generic_webpage_steps.rb:7
254
+
255
+ Scenario: Infrastructure developer can see generic webpage # features/generic_webpage.feature:14
256
+ Given a URL "http://generic-webpage.com" # features/step_definitions/generic_webpage_steps.rb:12
257
+ When I browse to the URL # features/step_definitions/generic_webpage_steps.rb:16
258
+ Then I should see "This is a generic webpage" # features/step_definitions/generic_webpage_steps.rb:23
259
+
260
+ 1 scenario (1 passed)
261
+ 5 steps (5 passed)
262
+ 1m25.227s
263
+ ```
22
264
 
23
265
  ## Contributing
24
266
 
data/TODO.md ADDED
@@ -0,0 +1,11 @@
1
+ # Things to do on Leibniz
2
+
3
+ - High level documentation
4
+ - Remove some nasty magic numbers
5
+ - On a physical box, prove that we can run a Leibniz job from Jenkins
6
+ - Try to get Leibniz to with TK to with the EC2 driver (or LXC / Docker)
7
+ - Demonstrate that this can work with Librarian?
8
+ - Demonstrate (and document) how to make Leibniz use the chef-zero provisioner
9
+ - Provide a generator which creates the outline stuff
10
+ - It'd be nice to be able to run the cucumber test and skip the teardown and setup process
11
+ - It'd be ace if we could not have to install chef each time (but that might mean a backed image)
data/WISHLIST.md ADDED
@@ -0,0 +1,85 @@
1
+ # Things I'd like this tool to have
2
+ ## in no particular order
3
+
4
+ ### Jenkins
5
+
6
+ Or some other other CI workflow. At present we have a pretty slick Continuous Deployment pipeline for our code. It would be great if we could run our infrastructure code through the same sort of system, because at the moment, although we have tools like Etsy's [knife-spork](https://github.com/jonlives/knife-spork) to guard against idiocy, it's basically gated by me. Fallible, error-prone me.
7
+
8
+ I know Zach mentioned something about a [Jenkins workflow](https://github.com/Atalanta/cucumber-chef/issues/101) a while ago, but I never heard anything more.
9
+
10
+ #### Current Status
11
+
12
+ - A project could be checked out and cucumber run by Jenkins or Travis
13
+ - However at present Leibniz only knows how to build machines via TK with the Vagrant driver
14
+ - This would mean we couldn't run it on Travis or on a 'cloud' Jenkins box; ie the Jenkins box would need to run Vagrant
15
+ - that said I'm not sure whether Vagrant itself would be able to use the EC2 'provider'?
16
+
17
+ #### Next Steps
18
+
19
+ - On a physical box, prove that we can run a Leibniz job from Jenkins
20
+ - Try to get Leibniz to with TK to with the EC2 driver (or LXC / Docker)
21
+
22
+ ### Test configuration per-project
23
+
24
+ [I mooted this back in April](https://github.com/Atalanta/cucumber-chef/pull/117) but then I went on holiday and kind of forgot about it. The somewhat lashed-together solution I came up with there looks a bit clunky now, but I think the idea still holds. Right now, I'm having to keep several different Labfiles around and symlink the correct one each time.
25
+
26
+ #### Current Status
27
+
28
+ - Leibniz simply provides an interface to Test Kitchen, and passes over a run list.
29
+ - This means we can have features / steps per project or per cookbook - whatever works
30
+
31
+ #### Next Steps
32
+
33
+ - Demonstrate that this can work with Librarian?
34
+
35
+
36
+ ### Looser coupling of moving parts
37
+
38
+ Here's the thing: the most complex project I'm currently managing with cuke-chef has 5 different types of node. In order to test things like Chef-search correctly, I need to spin up one of each from the Labfile, which incurs a huge first-run penalty. Subsequent runs are better, but still incredibly time-consuming as it seems to provision all the nodes on each run (which is not unreasonable, I guess).
39
+
40
+ Maybe there are already clever things I could with mocking and so on but I've never really looked into that. But whatever, being able to exercise only the required node(s) on a given test run (without commenting-out whole blocks from the Labfile, which is my current anti-pattern) would be splendid.
41
+
42
+ #### Current Status
43
+
44
+ - Acceptance tests shouldn't mock - we want to exercise all the pieces
45
+ - TK allows us to use Chef Zero - which gives us an in memory Chef server, including search, which is really really quick
46
+ - At lower levels (chefspec) we can stub the search and return data
47
+
48
+ #### Next Steps
49
+
50
+ - Demonstrate (and document) how to make Leibniz use the chef-zero provisioner
51
+
52
+ ### Full-stack testing
53
+
54
+ Right now, the way I'm using cuke-chef isn't at all BDD. My steps say things like
55
+
56
+ ```
57
+ Scenario: www vhost is correct
58
+ * file "/var/www/www/current/vhost" should contain
59
+ """
60
+ upstream www {
61
+ server 127.0.0.1:3020;
62
+ }
63
+
64
+ ```
65
+
66
+ whereas what I *should* care about would be more like
67
+
68
+ ```
69
+ Scenario: Home page
70
+ Given I am on "the home page"
71
+ Then I should see "All work and no play makes Jack a dull boy"
72
+ ```
73
+
74
+ Now of course this sort of stuff is tested in the apps themselves so maybe I'm looking at this from the wrong end, or maybe others are already doing this with cuke-chef and and I'm just Doing It Wrong.
75
+
76
+ But this, combined with the *Test configuration per-project* idea from above, would maybe let us test the entire stack from base OS to working app, which has a certain appeal.
77
+
78
+ #### Current Status
79
+
80
+ - The lower-level 'vhost is correct' steps should be run post-converge on the node under test using TK + whatever you want to write tests with (I recommend serverspec)
81
+ - The high-level BDD-style acceptance tests (the homepage does what it should) is precisely what Leibniz & Cucumber are for
82
+
83
+ # Annoyances with current cucumber-chef
84
+
85
+ * Occasional failure of packet-passing
data/bin/leibniz ADDED
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.join(File.dirname(__FILE__), %w{.. lib})
4
+ require 'thor'
5
+ require 'leibniz'
6
+ require 'pathname'
7
+
8
+ # Trap interrupts to quit cleanly. See
9
+ # https://twitter.com/mitchellh/status/283014103189053442
10
+ Signal.trap("INT") { exit 1 }
11
+
12
+ class LeibnizCli < Thor
13
+ include Thor::Actions
14
+
15
+ desc 'init', 'Set up a project ready for Leibniz Acceptance Testing'
16
+ def init
17
+ set_template_root
18
+ create_leibniz_yaml
19
+ create_skeleton_feature
20
+ append_to_gitignore(".leibniz/")
21
+ end
22
+
23
+ desc "version", "Print Leibniz's version information"
24
+ def version
25
+ say "Leibniz version #{Leibniz::VERSION}"
26
+ end
27
+ map %w(-v --version) => :version
28
+
29
+ private
30
+
31
+ def set_template_root
32
+ LeibnizCli.source_root Pathname.new(File.expand_path('../../templates', __FILE__))
33
+ end
34
+
35
+ def create_leibniz_yaml
36
+ empty_directory '.leibniz'
37
+ end
38
+
39
+ def create_skeleton_feature
40
+ directory 'features'
41
+ end
42
+
43
+ def append_to_gitignore(line)
44
+ create_file(".gitignore") unless File.exists?(File.join(destination_root, ".gitignore"))
45
+ if IO.readlines(File.join(destination_root, ".gitignore")).grep(%r{^#{line}}).empty?
46
+ append_to_file(".gitignore", "#{line}\n")
47
+ end
48
+ end
49
+
50
+ end
51
+
52
+ LeibnizCli.start
@@ -0,0 +1,15 @@
1
+ Feature: A command line interface for Leibniz
2
+ In order to simplify the process of getting started with Leibniz Acceptance Testing
3
+ As a Leibniz user
4
+ I want a command line interface that has sane defaults and built in help
5
+
6
+ Scenario: Displaying help
7
+ When I run `leibniz help`
8
+ Then the exit status should be 0
9
+ And the output should contain "leibniz init"
10
+ And the output should contain "leibniz version"
11
+
12
+ Scenario: Displaying the version of Leibniz
13
+ When I run `leibniz version`
14
+ Then the exit status should be 0
15
+ And the output should contain "Leibniz version"
@@ -0,0 +1,29 @@
1
+ Feature: Add Leibniz testing to an existing project
2
+ In order to get started with Leibniz
3
+ As an infrastructure developer
4
+ I want to run a command to initialize my project
5
+
6
+ Scenario: Displaying help
7
+ When I run `leibniz help init`
8
+ Then the output should contain:
9
+ """
10
+ Usage:
11
+ leibniz init
12
+ """
13
+ And the exit status should be 0
14
+
15
+ @announce
16
+ Scenario: Running leibniz init within a project
17
+ When I run `leibniz init`
18
+ Then the exit status should be 0
19
+ And a directory named ".leibniz" should exist
20
+ And a directory named "features/support" should exist
21
+ And the file "features/support/env.rb" should contain "require 'leibniz'"
22
+ And the file "features/learning_leibniz.feature" should contain:
23
+ """
24
+ Given I have provisioned the following infrastructure:
25
+ """
26
+ And a directory named "features/step_definitions" should exist
27
+ And the file "features/step_definitions/learning_steps.rb" should contain "@infrastructure.converge"
28
+ And the file ".gitignore" should contain ".leibniz/"
29
+
@@ -0,0 +1,6 @@
1
+ require 'aruba/cucumber'
2
+ require 'leibniz'
3
+
4
+ Before do
5
+ @aruba_timeout_seconds = 15
6
+ end
data/leibniz.gemspec CHANGED
@@ -20,7 +20,9 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.add_dependency "test-kitchen", "~> 1.0.0.alpha"
22
22
  spec.add_dependency "kitchen-vagrant"
23
+ spec.add_dependency "thor"
23
24
 
24
25
  spec.add_development_dependency "bundler", "~> 1.3"
26
+ spec.add_development_dependency 'aruba', '~> 0.5'
25
27
  spec.add_development_dependency "rake"
26
28
  end
@@ -1,3 +1,3 @@
1
1
  module Leibniz
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/leibniz.rb CHANGED
@@ -1,5 +1,4 @@
1
- require "leibniz/version"
2
-
1
+ require 'leibniz/version'
3
2
  require 'kitchen'
4
3
  require 'forwardable'
5
4
 
@@ -22,6 +21,7 @@ module Leibniz
22
21
 
23
22
  def self.build(specification)
24
23
  loader = KitchenLoader.new(specification)
24
+
25
25
  config = Kitchen::Config.new(:loader => loader)
26
26
  Infrastructure.new(config.instances)
27
27
  end
@@ -75,19 +75,31 @@ module Leibniz
75
75
  @platforms = specification.hashes.map do |spec|
76
76
  create_platform(spec)
77
77
  end
78
+ @suites = specification.hashes.map do |spec|
79
+ create_suite(spec)
80
+ end
78
81
  end
79
82
 
80
83
  def read
81
84
  {
82
85
  :driver_plugin => "vagrant",
83
86
  :platforms => platforms,
84
- :suites => [ { :name => "leibniz", :run_list => [] } ]
87
+ :suites => suites
85
88
  }
86
89
  end
87
90
 
88
91
  private
89
92
 
90
- attr_reader :platforms
93
+ attr_reader :platforms, :suites
94
+
95
+ def create_suite(spec)
96
+ suite = Hash.new
97
+ suite[:name] = 'leibniz'
98
+ suite[:run_list] = []
99
+ suite[:data_bags_path] = 'test/integration/default/data_bags'
100
+ suite
101
+ end
102
+
91
103
 
92
104
  def create_platform(spec)
93
105
  distro = "#{spec['Operating System']}-#{spec['Version']}"
@@ -0,0 +1,16 @@
1
+ Feature: Learn to use Leibniz
2
+
3
+ In order to learn how to use Leibniz
4
+ As an infrastructure developer
5
+ I want to be able to have a skeleton feature
6
+
7
+ Background:
8
+
9
+ Given I have provisioned the following infrastructure:
10
+ | Server Name | Operating System | Version | Chef Version | Run List |
11
+ | learning | centos | 6.4 | 11.8.0 | learning::default |
12
+ And I have run Chef
13
+
14
+ Scenario: Infrastructure developer can learn Leibniz
15
+ pending
16
+ # Write your features here!
@@ -0,0 +1,8 @@
1
+ Given(/^I have provisioned the following infrastructure:$/) do |specification|
2
+ @infrastructure = Leibniz.build(specification)
3
+ end
4
+
5
+ Given(/^I have run Chef$/) do
6
+ @infrastructure.destroy
7
+ @infrastructure.converge
8
+ end
@@ -0,0 +1 @@
1
+ require 'leibniz'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: leibniz
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.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-06-06 00:00:00.000000000 Z
12
+ date: 2013-11-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: test-kitchen
@@ -43,6 +43,22 @@ dependencies:
43
43
  - - ! '>='
44
44
  - !ruby/object:Gem::Version
45
45
  version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: thor
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
46
62
  - !ruby/object:Gem::Dependency
47
63
  name: bundler
48
64
  requirement: !ruby/object:Gem::Requirement
@@ -59,6 +75,22 @@ dependencies:
59
75
  - - ~>
60
76
  - !ruby/object:Gem::Version
61
77
  version: '1.3'
78
+ - !ruby/object:Gem::Dependency
79
+ name: aruba
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: '0.5'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: '0.5'
62
94
  - !ruby/object:Gem::Dependency
63
95
  name: rake
64
96
  requirement: !ruby/object:Gem::Requirement
@@ -78,7 +110,8 @@ dependencies:
78
110
  description: Integration Testing for Chef
79
111
  email:
80
112
  - stephen@atalanta-systems.com
81
- executables: []
113
+ executables:
114
+ - leibniz
82
115
  extensions: []
83
116
  extra_rdoc_files: []
84
117
  files:
@@ -87,9 +120,18 @@ files:
87
120
  - LICENSE.txt
88
121
  - README.md
89
122
  - Rakefile
123
+ - TODO.md
124
+ - WISHLIST.md
125
+ - bin/leibniz
126
+ - features/leibniz_command.feature
127
+ - features/leibniz_init.feature
128
+ - features/support/env.rb
90
129
  - leibniz.gemspec
91
130
  - lib/leibniz.rb
92
131
  - lib/leibniz/version.rb
132
+ - templates/features/learning_leibniz.feature
133
+ - templates/features/step_definitions/learning_steps.rb
134
+ - templates/features/support/env.rb
93
135
  homepage: ''
94
136
  licenses:
95
137
  - Apache 2.0
@@ -111,8 +153,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
111
153
  version: '0'
112
154
  requirements: []
113
155
  rubyforge_project:
114
- rubygems_version: 1.8.23
156
+ rubygems_version: 1.8.24
115
157
  signing_key:
116
158
  specification_version: 3
117
159
  summary: Arguably Leibniz independently invented integration.
118
- test_files: []
160
+ test_files:
161
+ - features/leibniz_command.feature
162
+ - features/leibniz_init.feature
163
+ - features/support/env.rb