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 +1 -0
- data/Gemfile +3 -0
- data/README.md +244 -2
- data/TODO.md +11 -0
- data/WISHLIST.md +85 -0
- data/bin/leibniz +52 -0
- data/features/leibniz_command.feature +15 -0
- data/features/leibniz_init.feature +29 -0
- data/features/support/env.rb +6 -0
- data/leibniz.gemspec +2 -0
- data/lib/leibniz/version.rb +1 -1
- data/lib/leibniz.rb +16 -4
- data/templates/features/learning_leibniz.feature +16 -0
- data/templates/features/step_definitions/learning_steps.rb +8 -0
- data/templates/features/support/env.rb +1 -0
- metadata +50 -5
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
# Leibniz
|
2
2
|
|
3
|
-
Leibniz is
|
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
|
-
|
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
|
+
|
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
|
data/lib/leibniz/version.rb
CHANGED
data/lib/leibniz.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
require
|
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 =>
|
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 @@
|
|
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.
|
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-
|
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.
|
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
|