puppet-testing 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +6 -0
- data/.rvmrc +1 -0
- data/Gemfile +16 -0
- data/Guardfile +14 -0
- data/Rakefile +2 -0
- data/features/PuppetRun.feature +9 -0
- data/features/Sanity.feature +10 -0
- data/features/step_defenitions/puppet_run.rb +23 -0
- data/features/step_defenitions/sanity.rb +48 -0
- data/lib/console.rb +8 -0
- data/lib/console/conversation.rb +65 -0
- data/lib/console/expectancies.rb +42 -0
- data/lib/console/kvm_machine.rb +43 -0
- data/lib/console/libvirt.rb +22 -0
- data/lib/puppet-testing.rb +5 -0
- data/lib/puppet-testing/version.rb +5 -0
- data/lib/ssh/port.rb +39 -0
- data/puppet-testing.gemspec +25 -0
- data/test/console/test_kvm_machine.rb +24 -0
- data/test/console/test_libvirt.rb +23 -0
- data/test/test_console.rb +1 -0
- data/test/test_helper.rb +9 -0
- metadata +149 -0
data/.gitignore
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm use ruby-1.8.7-p334
|
data/Gemfile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
gem 'ruby-libvirt' ,'0.3'
|
3
|
+
gem 'cucumber' ,'0.3'
|
4
|
+
gem 'rspec' , '1.3.1'
|
5
|
+
gem 'net-ssh'
|
6
|
+
gem 'fire_poll'
|
7
|
+
gem 'differ'
|
8
|
+
|
9
|
+
group :development do
|
10
|
+
gem 'irbtools'
|
11
|
+
gem 'minitest'
|
12
|
+
gem 'guard'
|
13
|
+
gem 'guard-minitest'
|
14
|
+
gem 'libnotify'
|
15
|
+
gem 'rb-inotify'
|
16
|
+
end
|
data/Guardfile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
guard 'minitest' do
|
5
|
+
# with Minitest::Unit
|
6
|
+
watch(%r|^test/(.*)/test_(.*)\.rb|)
|
7
|
+
watch(%r|^lib/(.*)/(.*)\.rb|) { |m| "test/#{m[1]}/test_#{m[2]}.rb" }
|
8
|
+
watch(%r|^test/test_helper\.rb|) { "test" }
|
9
|
+
|
10
|
+
# with Minitest::Spec
|
11
|
+
# watch(%r|^spec/(.*)_spec\.rb|)
|
12
|
+
# watch(%r|^lib/(.*)\.rb|) { |m| "spec/#{m[1]}_spec.rb" }
|
13
|
+
# watch(%r|^spec/spec_helper\.rb|) { "spec" }
|
14
|
+
end
|
data/Rakefile
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
Feature: Sanity
|
2
|
+
Vm lifecycle
|
3
|
+
|
4
|
+
Scenario: Vm manipulation and cleanup
|
5
|
+
When I start "puppet-client"
|
6
|
+
Then I should be able to ssh into "puppet-client"
|
7
|
+
Given I save into "/tmp/puppet-client.state"
|
8
|
+
And I touch "/tmp/sanity" on "puppet-client"
|
9
|
+
When I restore back "/tmp/puppet-client.state"
|
10
|
+
Then "/tmp/sanity" shouldn't exist on "puppet-client"
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'libvirt'
|
2
|
+
require 'net/ssh'
|
3
|
+
require 'lib/ssh/port'
|
4
|
+
|
5
|
+
Before do
|
6
|
+
@conn = Libvirt::open("qemu:///system")
|
7
|
+
end
|
8
|
+
|
9
|
+
|
10
|
+
Given /^the following vms are started:$/ do |table|
|
11
|
+
table.hashes.each do |hash|
|
12
|
+
@domain = @conn.lookup_domain_by_name(hash[:vm_name])
|
13
|
+
@domain.create if not @domain.active?
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
And /puppetd run on "(.*)"/ do |host|
|
18
|
+
ssh_after_boot(host,{:timeout => 60,:user => 'ronen'}) do |ssh|
|
19
|
+
ssh.exec!('puppetd --test --report').chomp
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'libvirt'
|
2
|
+
require 'net/ssh'
|
3
|
+
require 'lib/ssh/port'
|
4
|
+
begin require 'rspec'; rescue LoadError; require 'rspec/expectations'; end
|
5
|
+
|
6
|
+
Before do
|
7
|
+
@conn = Libvirt::open("qemu:///system")
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
When /I start "(.*)"/ do |name|
|
12
|
+
@domain = @conn.lookup_domain_by_name(name)
|
13
|
+
@domain.create if not @domain.active?
|
14
|
+
end
|
15
|
+
|
16
|
+
Then /I should be able to ssh into "(.*)"/ do |host|
|
17
|
+
result = ""
|
18
|
+
ssh_after_boot(host,{:timeout => 120,:user => 'ronen'}) do |ssh|
|
19
|
+
result = ssh.exec!('pwd').chomp
|
20
|
+
end
|
21
|
+
result.should == '/home/ronen'
|
22
|
+
end
|
23
|
+
|
24
|
+
Given /^I save into "(.*)"$/ do |file|
|
25
|
+
@domain.save(file)
|
26
|
+
@domain.create
|
27
|
+
end
|
28
|
+
|
29
|
+
When /I restore back "(.*)"/ do |file|
|
30
|
+
@domain.destroy
|
31
|
+
Libvirt::Domain::restore(@conn, file)
|
32
|
+
end
|
33
|
+
|
34
|
+
And /I touch "(.*)" on "(.*)"/ do |file,host|
|
35
|
+
ssh_to(host,{:timeout => 120,:user => 'ronen'}) do |ssh|
|
36
|
+
ssh.exec!("touch #{file}")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
Then /"(.*)" shouldn't exist on "(.*)"/ do |file,host|
|
42
|
+
result = ""
|
43
|
+
ssh_after_boot(host,{:timeout => 60,:user => 'ronen'}) do |ssh|
|
44
|
+
result = ssh.exec!("ls #{file}").chomp
|
45
|
+
end
|
46
|
+
result.should == 'ls: cannot access /tmp/sanity: No such file or directory'
|
47
|
+
|
48
|
+
end
|
data/lib/console.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
module Console
|
4
|
+
class Conversation
|
5
|
+
include Console::Expectancies
|
6
|
+
def initialize(domain)
|
7
|
+
shell = PTY.spawn "virsh console #{domain}"
|
8
|
+
@o,@i,@pid = shell[0],shell[1],shell[2]
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.talk_with(domain,&block)
|
12
|
+
conv = Conversation.new(domain)
|
13
|
+
begin
|
14
|
+
conv.instance_eval(&block)
|
15
|
+
ensure
|
16
|
+
conv.end_talk
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def enter(input)
|
21
|
+
@i.puts(input)
|
22
|
+
@i.flush
|
23
|
+
end
|
24
|
+
|
25
|
+
def exepecting(expected)
|
26
|
+
output =''
|
27
|
+
begin
|
28
|
+
FirePoll.poll(nil,5) do
|
29
|
+
output << read
|
30
|
+
output.eql?(expected)
|
31
|
+
end
|
32
|
+
rescue
|
33
|
+
puts 'diff exists between expected input and actual output:'
|
34
|
+
puts Differ.diff_by_char expected, output
|
35
|
+
end
|
36
|
+
puts output
|
37
|
+
output
|
38
|
+
end
|
39
|
+
|
40
|
+
def end_talk
|
41
|
+
enter '[^'
|
42
|
+
@o.close
|
43
|
+
@i.close
|
44
|
+
begin
|
45
|
+
Process.wait @pid
|
46
|
+
rescue PTY::ChildExited
|
47
|
+
rescue Errno::ECHILD
|
48
|
+
raise Exception.new 'console process not started, make sure domain is up and running'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def read
|
53
|
+
buffer = ""
|
54
|
+
begin
|
55
|
+
loop { buffer << @o.read_nonblock(10)}
|
56
|
+
rescue Errno::EAGAIN
|
57
|
+
# nothing to read now
|
58
|
+
rescue EOFError
|
59
|
+
# read was done
|
60
|
+
end
|
61
|
+
buffer
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Console
|
2
|
+
module Expectancies
|
3
|
+
def connected
|
4
|
+
res = <<-E
|
5
|
+
Connected to domain puppet-client\r
|
6
|
+
Escape character is ^]\r
|
7
|
+
E
|
8
|
+
end
|
9
|
+
|
10
|
+
def post_uname
|
11
|
+
res = <<-E
|
12
|
+
ronen
|
13
|
+
Password:
|
14
|
+
E
|
15
|
+
end
|
16
|
+
|
17
|
+
def logged_in
|
18
|
+
res = <<-E
|
19
|
+
Welcome to Ubuntu 11.04 (GNU/Linux 2.6.38-8-virtual x86_64)\r
|
20
|
+
|
21
|
+
* Documentation: https://help.ubuntu.com/\r
|
22
|
+
ronen@puppet-client:~$
|
23
|
+
E
|
24
|
+
end
|
25
|
+
|
26
|
+
def logout
|
27
|
+
res = <<-E
|
28
|
+
logout\r
|
29
|
+
\r
|
30
|
+
Ubuntu 11.04 puppet-client ttyS0\r
|
31
|
+
\r
|
32
|
+
puppet-client login:
|
33
|
+
E
|
34
|
+
end
|
35
|
+
|
36
|
+
def waiting_shell
|
37
|
+
"\r\nronen@puppet-client:~$ "
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'pty'
|
2
|
+
|
3
|
+
module Console
|
4
|
+
class KvmMachine
|
5
|
+
def initialize(domain)
|
6
|
+
@domain = domain
|
7
|
+
end
|
8
|
+
|
9
|
+
def login
|
10
|
+
Console::Conversation.talk_with(@domain) do
|
11
|
+
exepecting connected
|
12
|
+
enter 'ronen'
|
13
|
+
exepecting post_uname.chomp!
|
14
|
+
enter "xaL2ohM0"
|
15
|
+
sleep 3
|
16
|
+
puts read
|
17
|
+
# exepecting logged_in -> we can't match since it contains date
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
def execute(cli)
|
23
|
+
Console::Conversation.talk_with(@domain) do
|
24
|
+
exepecting connected
|
25
|
+
enter ''
|
26
|
+
exepecting waiting_shell
|
27
|
+
enter cli
|
28
|
+
exepecting waiting_shell
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
def logout
|
34
|
+
Console::Conversation.talk_with(@domain) do
|
35
|
+
exepecting connected
|
36
|
+
enter 'logout'
|
37
|
+
return exepecting logout.chomp!
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'etc'
|
2
|
+
|
3
|
+
PTS_PATH = '/dev/pts'
|
4
|
+
LIBVIRT_USER= 'libvirt-qemu'
|
5
|
+
LIBVIRT_GROUP= 'kvm'
|
6
|
+
|
7
|
+
module Console
|
8
|
+
class Libvirt
|
9
|
+
|
10
|
+
def initialize(path=PTS_PATH)
|
11
|
+
@pts_path=path
|
12
|
+
end
|
13
|
+
|
14
|
+
def libvirt_pts
|
15
|
+
Dir.entries(@pts_path).find_all do |pts|
|
16
|
+
uid = File.stat("#{@pts_path}/#{pts}").uid
|
17
|
+
Etc.getpwuid(uid).name.eql?(LIBVIRT_USER)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
data/lib/ssh/port.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'net/ssh'
|
2
|
+
|
3
|
+
def ssh_to(host, options = {} , &block)
|
4
|
+
Net::SSH.start(host,options[:user], options) do|ssh|
|
5
|
+
block.call(ssh)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def ssh_after_boot(host, options = {} , &block)
|
10
|
+
execute_when_tcp_available(host,options) do |host|
|
11
|
+
ssh_to(host,options) do |ssh|
|
12
|
+
block.call(ssh)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# see http://tinyurl.com/3ht46m5
|
18
|
+
def execute_when_tcp_available(ip, options = { } , &block)
|
19
|
+
defaults={ :port => 22, :timeout => 2 , :pollrate => 5}
|
20
|
+
options=defaults.merge(options)
|
21
|
+
begin
|
22
|
+
Timeout::timeout(options[:timeout]) do
|
23
|
+
connected=false
|
24
|
+
while !connected do
|
25
|
+
begin
|
26
|
+
s = TCPSocket.new(ip, options[:port])
|
27
|
+
s.close
|
28
|
+
block.call(ip)
|
29
|
+
return true
|
30
|
+
rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH, SocketError
|
31
|
+
sleep options[:pollrate]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
rescue Timeout::Error
|
36
|
+
raise 'timeout connecting to port'
|
37
|
+
end
|
38
|
+
return false
|
39
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "puppet-testing/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "puppet-testing"
|
7
|
+
s.version = Puppet::Testing::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["narkisr"]
|
10
|
+
s.email = ["narkisr@gmail.com"]
|
11
|
+
s.homepage = ""
|
12
|
+
s.summary = %q{A testing gem for puppet}
|
13
|
+
s.description = %q{Testing puppet using kvm and cucumber}
|
14
|
+
|
15
|
+
s.rubyforge_project = "puppet-testing"
|
16
|
+
s.add_dependency 'ruby-libvirt', '0.3'
|
17
|
+
s.add_dependency 'cucumber' , '0.3'
|
18
|
+
s.add_dependency 'rspec' , '1.3.1'
|
19
|
+
s.add_dependency 'net-ssh'
|
20
|
+
|
21
|
+
s.files = `git ls-files`.split("\n")
|
22
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
23
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
24
|
+
s.require_paths = ["lib"]
|
25
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'test_helper'
|
3
|
+
require 'console'
|
4
|
+
|
5
|
+
class TestPtyShell < MiniTest::Unit::TestCase
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@machine= Console::KvmMachine.new('puppet-client')
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_domain_down
|
12
|
+
machine = Console::KvmMachine.new('random-name')
|
13
|
+
assert_raises Exception do
|
14
|
+
machine.login
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_ls_la
|
19
|
+
@machine.login
|
20
|
+
assert_includes @machine.execute('ls -la'), 'total 36'
|
21
|
+
@machine.logout
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'test_helper'
|
3
|
+
require 'console'
|
4
|
+
require 'tmpdir'
|
5
|
+
|
6
|
+
class TestConsole < MiniTest::Unit::TestCase
|
7
|
+
include FileUtils
|
8
|
+
|
9
|
+
def test_pts_filtering
|
10
|
+
mocked_pts do |dir|
|
11
|
+
pts = Console::Libvirt.new(dir).libvirt_pts
|
12
|
+
assert_includes_all ['1','0'], pts
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def mocked_pts
|
17
|
+
Dir.mktmpdir('pts') do |dir|
|
18
|
+
%w(1 0 2 3 4).each {|p| touch "#{dir}/#{p}" }
|
19
|
+
%w(1 0).each {|p| chown LIBVIRT_USER, LIBVIRT_GROUP, "#{dir}/#{p}"}
|
20
|
+
yield dir
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
$LOAD_PATH.unshift( 'lib') unless $LOAD_PATH.include?('lib')
|
2
|
+
|
3
|
+
|
4
|
+
module MiniTest::Assertions
|
5
|
+
def assert_includes_all first , sec , msg =''
|
6
|
+
msg = message(msg) {"Expected #{sec.inspect} to contain all the elements of #{first.inspect}" }
|
7
|
+
assert first.all?{|e| sec.include?(e)} , msg
|
8
|
+
end
|
9
|
+
end
|
metadata
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: puppet-testing
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- narkisr
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-07-10 00:00:00 +03:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: ruby-libvirt
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - "="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 13
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
- 3
|
33
|
+
version: "0.3"
|
34
|
+
type: :runtime
|
35
|
+
version_requirements: *id001
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: cucumber
|
38
|
+
prerelease: false
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - "="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
hash: 13
|
45
|
+
segments:
|
46
|
+
- 0
|
47
|
+
- 3
|
48
|
+
version: "0.3"
|
49
|
+
type: :runtime
|
50
|
+
version_requirements: *id002
|
51
|
+
- !ruby/object:Gem::Dependency
|
52
|
+
name: rspec
|
53
|
+
prerelease: false
|
54
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - "="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
hash: 25
|
60
|
+
segments:
|
61
|
+
- 1
|
62
|
+
- 3
|
63
|
+
- 1
|
64
|
+
version: 1.3.1
|
65
|
+
type: :runtime
|
66
|
+
version_requirements: *id003
|
67
|
+
- !ruby/object:Gem::Dependency
|
68
|
+
name: net-ssh
|
69
|
+
prerelease: false
|
70
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
71
|
+
none: false
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
hash: 3
|
76
|
+
segments:
|
77
|
+
- 0
|
78
|
+
version: "0"
|
79
|
+
type: :runtime
|
80
|
+
version_requirements: *id004
|
81
|
+
description: Testing puppet using kvm and cucumber
|
82
|
+
email:
|
83
|
+
- narkisr@gmail.com
|
84
|
+
executables: []
|
85
|
+
|
86
|
+
extensions: []
|
87
|
+
|
88
|
+
extra_rdoc_files: []
|
89
|
+
|
90
|
+
files:
|
91
|
+
- .gitignore
|
92
|
+
- .rvmrc
|
93
|
+
- Gemfile
|
94
|
+
- Gemfile.lock
|
95
|
+
- Guardfile
|
96
|
+
- Rakefile
|
97
|
+
- features/PuppetRun.feature
|
98
|
+
- features/Sanity.feature
|
99
|
+
- features/step_defenitions/puppet_run.rb
|
100
|
+
- features/step_defenitions/sanity.rb
|
101
|
+
- lib/console.rb
|
102
|
+
- lib/console/conversation.rb
|
103
|
+
- lib/console/expectancies.rb
|
104
|
+
- lib/console/kvm_machine.rb
|
105
|
+
- lib/console/libvirt.rb
|
106
|
+
- lib/puppet-testing.rb
|
107
|
+
- lib/puppet-testing/version.rb
|
108
|
+
- lib/ssh/port.rb
|
109
|
+
- puppet-testing.gemspec
|
110
|
+
- test/console/test_kvm_machine.rb
|
111
|
+
- test/console/test_libvirt.rb
|
112
|
+
- test/test_console.rb
|
113
|
+
- test/test_helper.rb
|
114
|
+
has_rdoc: true
|
115
|
+
homepage: ""
|
116
|
+
licenses: []
|
117
|
+
|
118
|
+
post_install_message:
|
119
|
+
rdoc_options: []
|
120
|
+
|
121
|
+
require_paths:
|
122
|
+
- lib
|
123
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
124
|
+
none: false
|
125
|
+
requirements:
|
126
|
+
- - ">="
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
hash: 3
|
129
|
+
segments:
|
130
|
+
- 0
|
131
|
+
version: "0"
|
132
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
133
|
+
none: false
|
134
|
+
requirements:
|
135
|
+
- - ">="
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
hash: 3
|
138
|
+
segments:
|
139
|
+
- 0
|
140
|
+
version: "0"
|
141
|
+
requirements: []
|
142
|
+
|
143
|
+
rubyforge_project: puppet-testing
|
144
|
+
rubygems_version: 1.6.2
|
145
|
+
signing_key:
|
146
|
+
specification_version: 3
|
147
|
+
summary: A testing gem for puppet
|
148
|
+
test_files: []
|
149
|
+
|