skewer 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.idea/encodings.xml +5 -0
- data/.idea/misc.xml +8 -0
- data/.idea/modules.xml +9 -0
- data/.idea/skewer.iml +61 -0
- data/.idea/vcs.xml +7 -0
- data/.rvmrc +2 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +146 -0
- data/LICENSE +13 -0
- data/README.md +77 -0
- data/Rakefile +59 -0
- data/Vagrantfile +5 -0
- data/assets/Gemfile +5 -0
- data/assets/rubygems.sh +39 -0
- data/bin/skewer +101 -0
- data/features/aws.feature +45 -0
- data/features/bootstrapper.feature +14 -0
- data/features/configuration.feature +15 -0
- data/features/delete.feature +22 -0
- data/features/hooks.feature +15 -0
- data/features/interface.feature +61 -0
- data/features/provision.feature +38 -0
- data/features/rackspace.feature +34 -0
- data/features/step_definitions/cucumber_steps.rb +43 -0
- data/features/step_definitions/delete.rb +32 -0
- data/features/support/env.rb +6 -0
- data/features/support/puppetcode/manifests/classes/foobar.pp +4 -0
- data/features/support/puppetcode/manifests/classes/foobroken.pp +4 -0
- data/features/support/puppetcode/manifests/classes/role.pp +3 -0
- data/features/support/puppetcode/manifests/site.pp +2 -0
- data/features/support/puppetcode/modules/foo/manifests/bar.pp +3 -0
- data/features/support/puppetcode/modules/foo/manifests/broken.pp +8 -0
- data/features/support/puppetcode/modules/puppet/manifests/munge.pp +5 -0
- data/features/update.feature +29 -0
- data/lib/aws/node.rb +52 -0
- data/lib/aws/security_group.rb +37 -0
- data/lib/aws/service.rb +21 -0
- data/lib/bootstrapper.rb +112 -0
- data/lib/cli.rb +96 -0
- data/lib/config.rb +67 -0
- data/lib/cuke.rb +26 -0
- data/lib/ersatz/ersatz_node.rb +31 -0
- data/lib/ersatz/ssh_result.rb +15 -0
- data/lib/eucalyptus.rb +15 -0
- data/lib/hooks.rb +22 -0
- data/lib/node.erb +5 -0
- data/lib/node.rb +43 -0
- data/lib/parser.rb +92 -0
- data/lib/puppet.rb +53 -0
- data/lib/puppet_node.rb +26 -0
- data/lib/puppet_runtime_error.rb +6 -0
- data/lib/rackspace/images.rb +25 -0
- data/lib/rackspace/node.rb +60 -0
- data/lib/skewer.rb +13 -0
- data/lib/skewer/version.rb +3 -0
- data/lib/source.rb +54 -0
- data/lib/stub_node.rb +25 -0
- data/lib/util.rb +17 -0
- data/skewer.gemspec +30 -0
- data/spec/aws/node_spec.rb +70 -0
- data/spec/aws/security_group_spec.rb +20 -0
- data/spec/aws/service_spec.rb +31 -0
- data/spec/bootstrapper_spec.rb +116 -0
- data/spec/cli_spec.rb +71 -0
- data/spec/config_spec.rb +68 -0
- data/spec/cuke_spec.rb +46 -0
- data/spec/ersatz_node_spec.rb +9 -0
- data/spec/ersatz_ssh_result_spec.rb +16 -0
- data/spec/hooks_spec.rb +19 -0
- data/spec/logger_spec.rb +22 -0
- data/spec/parser_spec.rb +93 -0
- data/spec/puppet.rb +47 -0
- data/spec/puppet_node_spec.rb +31 -0
- data/spec/rackspace/images_spec.rb +37 -0
- data/spec/rackspace/node_spec.rb +30 -0
- data/spec/source_spec.rb +45 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/support/features/example.feature +9 -0
- data/spec/support/features/step_definitions/example.rb +8 -0
- data/spec/util_spec.rb +27 -0
- metadata +288 -0
data/bin/skewer
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$: << File.join(File.dirname(__FILE__), '..', 'lib')
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
require 'optparse'
|
6
|
+
require 'parser'
|
7
|
+
|
8
|
+
options = {:kind => :ersatz}
|
9
|
+
|
10
|
+
type = ARGV.shift
|
11
|
+
|
12
|
+
optparse = OptionParser.new do |opts|
|
13
|
+
#
|
14
|
+
# Provision
|
15
|
+
#
|
16
|
+
opts.on('-c', '--cloud KIND', "Cloud kind ('ec2', 'linode', 'rackspace')") do |c|
|
17
|
+
options[:kind] = c.to_sym
|
18
|
+
end
|
19
|
+
|
20
|
+
opts.on('-r', '--role NAME', "puppet role class to call") do |r|
|
21
|
+
options[:role] = r
|
22
|
+
end
|
23
|
+
|
24
|
+
opts.on('-pc', '--puppetcode') do |pc|
|
25
|
+
options[:puppet_repo] = pc
|
26
|
+
puts "puppetcode is: " + pc
|
27
|
+
end
|
28
|
+
|
29
|
+
opts.on('-m', '--mock') do
|
30
|
+
options[:mock] = true
|
31
|
+
end
|
32
|
+
|
33
|
+
opts.on('--keep') do
|
34
|
+
options[:keep] = true
|
35
|
+
end
|
36
|
+
|
37
|
+
opts.on('-hk', '--hook') do |hook|
|
38
|
+
options[:hook] = hook
|
39
|
+
end
|
40
|
+
|
41
|
+
# AWS options
|
42
|
+
opts.on('-i', '--image NAME') do |img|
|
43
|
+
options[:image] = img
|
44
|
+
end
|
45
|
+
opts.on('--volume SIZE') do |vol|
|
46
|
+
# EBS group
|
47
|
+
options[:volume] = vol
|
48
|
+
end
|
49
|
+
opts.on('--region NAME') do |region|
|
50
|
+
# AWS region
|
51
|
+
options[:region] = region
|
52
|
+
end
|
53
|
+
opts.on('--key', '--key_name NAME') do |k|
|
54
|
+
# AWS SSH key
|
55
|
+
options[:key_name] = k
|
56
|
+
end
|
57
|
+
opts.on('--group NAME') do |group|
|
58
|
+
# EC2 Security Group
|
59
|
+
options[:group] = group
|
60
|
+
end
|
61
|
+
opts.on('--flavor FLAVOR') do |flavor|
|
62
|
+
# AWS instance size
|
63
|
+
options[:flavor_id] = flavor
|
64
|
+
end
|
65
|
+
|
66
|
+
#
|
67
|
+
# Updating.
|
68
|
+
#
|
69
|
+
# TODO: This shouldn't be -h for hostname.
|
70
|
+
opts.on('-h', '--host KIND', "Hostname to update") do |c|
|
71
|
+
options[:host] = c
|
72
|
+
end
|
73
|
+
opts.on('-u', '--user KIND', "User to connect with") do |u|
|
74
|
+
options[:user] = u
|
75
|
+
end
|
76
|
+
opts.on('-r', '--role NAME', "puppet role class to call") do |r|
|
77
|
+
options[:role] = r
|
78
|
+
end
|
79
|
+
opts.on('-n', '--noop', "do a dry run first") do
|
80
|
+
options[:noop] = true
|
81
|
+
end
|
82
|
+
opts.on('-pc', '--puppetcode') do |pc|
|
83
|
+
options[:puppet_repo] = pc
|
84
|
+
puts "puppetcode is: " + pc
|
85
|
+
end
|
86
|
+
|
87
|
+
opts.on('--features DIRECTORY') do |dir|
|
88
|
+
options[:cuke_dir] = dir
|
89
|
+
end
|
90
|
+
|
91
|
+
# TODO: Fix this, and update the above for --host/-h
|
92
|
+
opts.on('-q', '--help') do
|
93
|
+
options[:help] = true
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
optparse.parse!
|
98
|
+
|
99
|
+
Fog.mock! if options[:mock]
|
100
|
+
|
101
|
+
Skewer::CLI::Parser.new(type, options)
|
@@ -0,0 +1,45 @@
|
|
1
|
+
Feature: provisioning a node on AWS
|
2
|
+
In order to run my puppet code on a new AWS machine
|
3
|
+
As someone who wants to deploy something to the machine
|
4
|
+
I want to run the provision command
|
5
|
+
|
6
|
+
@announce-stdout
|
7
|
+
@announce-stderr
|
8
|
+
|
9
|
+
Scenario: Roll out AWS node and configure it
|
10
|
+
Given I have puppet code in "/tmp/skewer_test_code"
|
11
|
+
And a file named ".skewer.json" with:
|
12
|
+
"""
|
13
|
+
{"puppet_repo": "/tmp/skewer_test_code" }
|
14
|
+
"""
|
15
|
+
When I run `./bin/skewer provision --cloud ec2 --role foobar --image ami-5c9b4935 --key testytesty`
|
16
|
+
Then the exit status should be 0
|
17
|
+
And the stdout should contain "Puppet run succeeded"
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
Scenario: Roll out AWS node and configure it without a JSON file
|
22
|
+
Given I have puppet code in "/tmp/skewer_test_code"
|
23
|
+
When I run `./bin/skewer provision --cloud ec2 --role foobar --image ami-5c9b4935 --key testytesty --puppetcode /tmp/skewer_test_code`
|
24
|
+
Then the exit status should be 0
|
25
|
+
And the stdout should contain "Puppet run succeeded"
|
26
|
+
|
27
|
+
|
28
|
+
@announce-stdout
|
29
|
+
@announce-stderr
|
30
|
+
@wip
|
31
|
+
Scenario: Roll out AWS node with a specific region
|
32
|
+
Given I have puppet code in "/tmp/skewer_test_code"
|
33
|
+
When I run `./bin/skewer provision --cloud ec2 --role foobar --image ami-f6340182 --region eu-west-1 --key testytesty --puppetcode /tmp/skewer_test_code`
|
34
|
+
Then the exit status should be 0
|
35
|
+
And the stdout should contain "Puppet run succeeded"
|
36
|
+
|
37
|
+
|
38
|
+
Scenario: Roll out AWS node with a specific size
|
39
|
+
Given I have puppet code in "/tmp/skewer_test_code"
|
40
|
+
And a file named ".skewer.json" with:
|
41
|
+
"""
|
42
|
+
{"puppet_repo": "/tmp/skewer_test_code" }
|
43
|
+
"""
|
44
|
+
When I run `./bin/skewer provision --cloud ec2 --role foobar --image ami-5c9b4935 --flavor m1.small --key testytesty`
|
45
|
+
Then the stdout should contain "Puppet run succeeded"
|
@@ -0,0 +1,14 @@
|
|
1
|
+
Feature: valid bash bootstrap code
|
2
|
+
In order to run the tool
|
3
|
+
As a user
|
4
|
+
I want the bootstrap code to work
|
5
|
+
|
6
|
+
Scenario: valid bash file
|
7
|
+
When I run `bash -nx assets/rubygems.sh`
|
8
|
+
Then the exit status should be 0
|
9
|
+
|
10
|
+
Scenario: only indents should be tabs
|
11
|
+
When a file named "assets/rubygems.sh" should exist
|
12
|
+
Then the file "assets/rubygems.sh" shouldnt match "^ +"
|
13
|
+
And the file "assets/rubygems.sh" should match "^\t"
|
14
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
Feature: Configuration
|
2
|
+
In order to tell Skewer what I am doing
|
3
|
+
As a user
|
4
|
+
I want it to accept a config file
|
5
|
+
|
6
|
+
Scenario: read config from project directory
|
7
|
+
Given a file named ".skewer.json" with:
|
8
|
+
"""
|
9
|
+
{"puppet_repo":"/foo/bar/baz"}
|
10
|
+
"""
|
11
|
+
When I run `./bin/skewer provision --cloud stub --image foo --role bar`
|
12
|
+
Then the stdout should contain "Using Puppet Code from /foo/bar/baz"
|
13
|
+
|
14
|
+
Scenario: read config from home directory
|
15
|
+
|
@@ -0,0 +1,22 @@
|
|
1
|
+
Feature: updating a node
|
2
|
+
In order to delete a node
|
3
|
+
As a someone who knows the cloud and host address
|
4
|
+
I want to run the delete command
|
5
|
+
|
6
|
+
@announce-stdout @announce-stderr
|
7
|
+
Scenario: run the command with bad input
|
8
|
+
When I run `./bin/skewer delete --cloud ec2 --host bleh --key ~/.ssh/testytest.pem`
|
9
|
+
Then the stderr should contain "bleh not found"
|
10
|
+
And the exit status should not be 0
|
11
|
+
|
12
|
+
@announce-stdout @announce-stderr
|
13
|
+
Scenario: run the command with bad input
|
14
|
+
When I run `./bin/skewer delete --cloud ec2 --host bleh --key ~/.ssh/testytest.pem`
|
15
|
+
Then the stderr should contain "bleh not found"
|
16
|
+
And the exit status should not be 0
|
17
|
+
|
18
|
+
@wip @announce-stdout @announce-stderr
|
19
|
+
Scenario: create a new Rackspace server and delete it
|
20
|
+
Given I create a new Rackspace server
|
21
|
+
When I delete the new Rackspace server I created
|
22
|
+
Then the output should say that the Rackspace server was deleted
|
@@ -0,0 +1,15 @@
|
|
1
|
+
Feature: Hooks
|
2
|
+
In order to integrate Skewer with other processes
|
3
|
+
As a user
|
4
|
+
I want it to execute a command when it's finihsed
|
5
|
+
|
6
|
+
Scenario: accept hook on CLI
|
7
|
+
Given a file named "/tmp/skewer_hook" with:
|
8
|
+
"""
|
9
|
+
#!/bin/bash
|
10
|
+
echo $1 > /tmp/skewer_hook_result
|
11
|
+
"""
|
12
|
+
And I run `chmod +x /tmp/skewer_hook`
|
13
|
+
When I run `./bin/skewer provision --cloud stub --image foo --role bar --hook /tmp/skewer_hook`
|
14
|
+
Then the file "/tmp/skewer_hook_result" should exist
|
15
|
+
|
@@ -0,0 +1,61 @@
|
|
1
|
+
Feature: help output for the skewer command-line tool
|
2
|
+
In order to get sufficient feedback
|
3
|
+
As someone who wants to use skewer
|
4
|
+
When I do something wrong or provide the help option
|
5
|
+
I want the help messages to appear
|
6
|
+
|
7
|
+
Scenario: run the command without arguments
|
8
|
+
When I run `./bin/skewer`
|
9
|
+
Then the output should contain:
|
10
|
+
"""
|
11
|
+
Usage: skewer COMMAND [options]
|
12
|
+
|
13
|
+
The available skewer commands are:
|
14
|
+
provision spawn a new VM via a cloud system and provision it with puppet code
|
15
|
+
update update the puppet code on a machine that you've already provisioned
|
16
|
+
"""
|
17
|
+
And the exit status should not be 0
|
18
|
+
|
19
|
+
Scenario: run the command with help option
|
20
|
+
When I run `./bin/skewer --help`
|
21
|
+
Then the output should contain:
|
22
|
+
"""
|
23
|
+
Usage: skewer COMMAND [options]
|
24
|
+
|
25
|
+
The available skewer commands are:
|
26
|
+
provision spawn a new VM via a cloud system and provision it with puppet code
|
27
|
+
update update the puppet code on a machine that you've already provisioned
|
28
|
+
"""
|
29
|
+
And the exit status should not be 0
|
30
|
+
|
31
|
+
Scenario: run the provision command without arguments
|
32
|
+
When I run `./bin/skewer provision`
|
33
|
+
Then the output should contain:
|
34
|
+
"""
|
35
|
+
Usage: skewer provision --cloud <which cloud> --image <AWS image> --role <puppet role class>
|
36
|
+
"""
|
37
|
+
And the exit status should not be 0
|
38
|
+
|
39
|
+
Scenario: run the provision command with help arguments
|
40
|
+
When I run `./bin/skewer provision --help`
|
41
|
+
Then the output should contain:
|
42
|
+
"""
|
43
|
+
Usage: skewer provision --cloud <which cloud> --image <AWS image> --role <puppet role class>
|
44
|
+
"""
|
45
|
+
And the exit status should not be 0
|
46
|
+
|
47
|
+
Scenario: run the update command without arguments
|
48
|
+
When I run `./bin/skewer update`
|
49
|
+
Then the output should contain:
|
50
|
+
"""
|
51
|
+
Usage: skewer update --host <host> --user <user with sudo rights> --role <puppet role class>
|
52
|
+
"""
|
53
|
+
And the exit status should not be 0
|
54
|
+
|
55
|
+
Scenario: run the update command with help arguments
|
56
|
+
When I run `./bin/skewer update --help`
|
57
|
+
Then the output should contain:
|
58
|
+
"""
|
59
|
+
Usage: skewer update --host <host> --user <user with sudo rights> --role <puppet role class>
|
60
|
+
"""
|
61
|
+
And the exit status should not be 0
|
@@ -0,0 +1,38 @@
|
|
1
|
+
Feature: provisioning a node
|
2
|
+
In order to run my puppet code for the first time
|
3
|
+
As a someone who wants to deploy something to the machine
|
4
|
+
I want to run the provision command
|
5
|
+
|
6
|
+
@puts
|
7
|
+
Scenario: run the command without args
|
8
|
+
When I run `./bin/skewer provision`
|
9
|
+
Then the exit status should not be 0
|
10
|
+
|
11
|
+
@announce-stdout
|
12
|
+
@announce-stderr
|
13
|
+
Scenario: pass in a cloud image and role
|
14
|
+
When I run `./bin/skewer provision --cloud stub --image foo --role foo`
|
15
|
+
Then the exit status should be 0
|
16
|
+
|
17
|
+
@announce-stdout
|
18
|
+
@announce-stderr
|
19
|
+
Scenario: config in local file
|
20
|
+
Given I have puppet code in "/tmp/skewer_test_code"
|
21
|
+
And a file named ".skewer.json" with:
|
22
|
+
"""
|
23
|
+
{"puppet_repo":"/tmp/skewer_test_code"}
|
24
|
+
"""
|
25
|
+
When I run `./bin/skewer provision --cloud stub --role foobar --image ami-deadbeef`
|
26
|
+
Then the stdout should contain "Using Puppet Code from /tmp/skewer_test_code"
|
27
|
+
And the exit status should be 0
|
28
|
+
|
29
|
+
@announce-stdout
|
30
|
+
@announce-stderr
|
31
|
+
Scenario: generated node file
|
32
|
+
Given I have puppet code in "/tmp/more_skewer_test_code"
|
33
|
+
And a file named ".skewer.json" with:
|
34
|
+
"""
|
35
|
+
{"puppet_repo":"/tmp/skewer_test_code"}
|
36
|
+
"""
|
37
|
+
When I run `./bin/skewer provision --cloud stub --role foobar --image ami-deadbeef`
|
38
|
+
Then the file "/tmp/more_skewer_test_code/manifests/nodes.pp" should exist
|
@@ -0,0 +1,34 @@
|
|
1
|
+
Feature: provisioning a node on Rackspace
|
2
|
+
In order to run my puppet code on a new Rackspace machine
|
3
|
+
As someone who wants to deploy something to the machine
|
4
|
+
I want to run the provision command
|
5
|
+
|
6
|
+
@announce-stdout
|
7
|
+
@announce-stderr
|
8
|
+
Scenario: config in local file
|
9
|
+
Given I have puppet code in "/tmp/skewer_test_code"
|
10
|
+
And a file named ".skewer.json" with:
|
11
|
+
"""
|
12
|
+
{
|
13
|
+
"puppet_repo":"/tmp/skewer_test_code",
|
14
|
+
"flavor_id":"1",
|
15
|
+
"image_id":"112"
|
16
|
+
}
|
17
|
+
"""
|
18
|
+
When I run `./bin/skewer provision --cloud rackspace --role foobar --image 112`
|
19
|
+
Then the stdout should contain "Evaluating cloud rackspace"
|
20
|
+
And the stdout should contain "Launching a Rackspace node"
|
21
|
+
|
22
|
+
@announce-stdout
|
23
|
+
@announce-stderr
|
24
|
+
Scenario: Build a machine with a specific flavor (RAM size)
|
25
|
+
Given I run `./bin/skewer provision --cloud rackspace --role foobar --image 112 --flavor 3`
|
26
|
+
Then the stdout should contain "Evaluating cloud rackspace"
|
27
|
+
And the stdout should contain "Launching a Rackspace node"
|
28
|
+
|
29
|
+
@announce-stdout
|
30
|
+
@announce-stderr
|
31
|
+
Scenario: Build a machine with a symbolic image ID
|
32
|
+
Given I run `./bin/skewer provision --cloud rackspace --role foobar --image ubuntu1104 --flavor 2`
|
33
|
+
Then the stdout should contain "Evaluating cloud rackspace"
|
34
|
+
And the stdout should contain "Launching a Rackspace node"
|
@@ -0,0 +1,43 @@
|
|
1
|
+
Before do
|
2
|
+
config_file = File.join(File.dirname(__FILE__), '../..', '.skewer.json')
|
3
|
+
puts "Checking for #{config_file}"
|
4
|
+
if File.exists?(config_file)
|
5
|
+
puts "Removing #{config_file}"
|
6
|
+
FileUtils.rm_f(config_file)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
Given /^I have puppet code in "([^"]*)"$/ do |dir|
|
11
|
+
|
12
|
+
puppet_code_source = File.join(File.dirname(__FILE__), '../support/puppetcode')
|
13
|
+
puts "Copying #{puppet_code_source} to #{dir}"
|
14
|
+
FileUtils.cp_r(puppet_code_source, dir) unless File.exists?(dir)
|
15
|
+
@puppet_repo = dir
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
require 'resolv-replace'
|
20
|
+
require 'ping'
|
21
|
+
|
22
|
+
def internet_connection?
|
23
|
+
Ping.pingecho "google.com", 1, 80
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
Given /^I have access to the internet$/ do
|
28
|
+
internet_connection?.should == true
|
29
|
+
end
|
30
|
+
|
31
|
+
Then /^the file "([^"]*)" should exist$/ do |file|
|
32
|
+
File.exists?(file).should == true
|
33
|
+
end
|
34
|
+
|
35
|
+
Then /^the file "([^"]*)" (.*) match "([^"]*)"$/ do |file, condition, expr|
|
36
|
+
file_contents = File.read(file)
|
37
|
+
if condition == 'should'
|
38
|
+
file_contents.should match expr
|
39
|
+
else
|
40
|
+
file_contents.should_not match expr
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'fog'
|
2
|
+
|
3
|
+
Given /^I create a new Rackspace server$/ do
|
4
|
+
build = lambda {
|
5
|
+
service = Fog::Compute.new(
|
6
|
+
:provider => 'Rackspace',
|
7
|
+
:rackspace_auth_url => "lon.auth.api.rackspacecloud.com")
|
8
|
+
path = File.expand_path '~/.ssh/id_rsa.pub'
|
9
|
+
path = File.expand_path '~/.ssh/id_dsa.pub' if not File.exist? path
|
10
|
+
key = File.open(path, 'rb').read
|
11
|
+
return service.servers.bootstrap({
|
12
|
+
:flavor_id => 1,
|
13
|
+
:image_id => 112,
|
14
|
+
:name => "i-shouldnt-exist",
|
15
|
+
:public_key => key})
|
16
|
+
}
|
17
|
+
@node = build.call
|
18
|
+
@ip_address = node.public_ip_address
|
19
|
+
end
|
20
|
+
|
21
|
+
When /^I delete the new Rackspace server I created$/ do
|
22
|
+
ip = @ip_address
|
23
|
+
# The 2>&1 tells shell to redirect stderr to stdout.
|
24
|
+
@out = `./bin/skewer delete --cloud rackspace --host #{ip} 2>&1`
|
25
|
+
end
|
26
|
+
|
27
|
+
Then /^the output should say that the Rackspace server was deleted$/ do
|
28
|
+
ip = @ip_address
|
29
|
+
match = @out.match("#{ip} deleted")
|
30
|
+
match.should_not == nil
|
31
|
+
match.class.should == MatchData
|
32
|
+
end
|