serverspec-extended-types 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +22 -0
- data/.rspec +2 -0
- data/.travis.yml +13 -0
- data/.yardopts +1 -0
- data/CHANGES.md +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +249 -0
- data/Rakefile +53 -0
- data/lib/serverspec_extended_types.rb +4 -0
- data/lib/serverspec_extended_types/bitlbee.rb +204 -0
- data/lib/serverspec_extended_types/http_get.rb +159 -0
- data/lib/serverspec_extended_types/version.rb +3 -0
- data/lib/serverspec_extended_types/virtualenv.rb +161 -0
- data/serverspec-extended-types.gemspec +31 -0
- data/spec/spec_helper.rb +42 -0
- data/spec/types/bitlbee_spec.rb +189 -0
- data/spec/types/http_get_spec.rb +75 -0
- data/spec/types/virtualenv_spec.rb +201 -0
- metadata +223 -0
@@ -0,0 +1,159 @@
|
|
1
|
+
##############################################################################
|
2
|
+
# serverspec-extended-types - http_get
|
3
|
+
#
|
4
|
+
# <https://github.com/jantman/serverspec-extended-types>
|
5
|
+
#
|
6
|
+
# Copyright (C) 2015 Jason Antman <jason@jasonantman.com>
|
7
|
+
#
|
8
|
+
# Licensed under the MIT License - see LICENSE.txt
|
9
|
+
#
|
10
|
+
##############################################################################
|
11
|
+
|
12
|
+
require 'timeout'
|
13
|
+
require 'faraday'
|
14
|
+
require 'serverspec_extended_types/version'
|
15
|
+
|
16
|
+
module Serverspec
|
17
|
+
module Type
|
18
|
+
|
19
|
+
# Perform an HTTP GET request against the serverspec target
|
20
|
+
# using {http://www.rubydoc.info/gems/faraday/ Faraday}.
|
21
|
+
class Http_Get < Base
|
22
|
+
|
23
|
+
# Initialize a bunch of instance variables, then call {#getpage}
|
24
|
+
#
|
25
|
+
# Calls {#getpage} within a {Timeout::timeout} block;
|
26
|
+
# If {#getpage} times out, set ``timed_out_status`` to [True]
|
27
|
+
#
|
28
|
+
# @param port [Int] the port to connect to HTTP over
|
29
|
+
# @param host_header [String] the value to set in the 'Host' HTTP request header
|
30
|
+
# @param path [String] the URI/path to request from the server
|
31
|
+
# @param timeout_sec [Int] how many seconds to allow request to run before timing out and setting @timed_out_status to True
|
32
|
+
#
|
33
|
+
# @example
|
34
|
+
# describe http_get(80, 'myhostname', '/') do
|
35
|
+
# # tests here
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# @api public
|
39
|
+
# @return [nil]
|
40
|
+
def initialize(port, host_header, path, timeout_sec=10)
|
41
|
+
@ip = ENV['TARGET_HOST']
|
42
|
+
@port = port
|
43
|
+
@host = host_header
|
44
|
+
@path = path
|
45
|
+
@timed_out_status = false
|
46
|
+
@content_str = nil
|
47
|
+
@headers_hash = nil
|
48
|
+
@response_code_int = nil
|
49
|
+
begin
|
50
|
+
Timeout::timeout(timeout_sec) do
|
51
|
+
getpage
|
52
|
+
end
|
53
|
+
rescue Timeout::Error
|
54
|
+
@timed_out_status = true
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Private method to actually get the page; must be called within a timeout block
|
59
|
+
#
|
60
|
+
# Gets the page using {http://www.rubydoc.info/gems/faraday/ Faraday} and then sets instance variables for the various attribute readers.
|
61
|
+
#
|
62
|
+
# @api private
|
63
|
+
# @return [nil]
|
64
|
+
def getpage
|
65
|
+
ip = @ip
|
66
|
+
port = @port
|
67
|
+
conn = Faraday.new("http://#{ip}:#{port}/")
|
68
|
+
version = ServerspecExtendedTypes::VERSION
|
69
|
+
conn.headers[:user_agent] = "Serverspec::Type::Http_Get/#{version} (https://github.com/jantman/serverspec-extended-types)"
|
70
|
+
conn.headers[:Host] = @host
|
71
|
+
response = conn.get(@path)
|
72
|
+
@response_code_int = response.status
|
73
|
+
@content_str = response.body
|
74
|
+
@headers_hash = Hash.new('')
|
75
|
+
response.headers.each do |header, val|
|
76
|
+
@headers_hash[header] = val
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Whether or not the request timed out
|
81
|
+
#
|
82
|
+
# @example
|
83
|
+
# describe http_get(80, 'myhostname', '/') do
|
84
|
+
# it { should_not be_timed_out }
|
85
|
+
# end
|
86
|
+
#
|
87
|
+
# @api public
|
88
|
+
# @return [Boolean]
|
89
|
+
def timed_out?
|
90
|
+
@timed_out_status
|
91
|
+
end
|
92
|
+
|
93
|
+
# Returns the HTTP response headers as a hash
|
94
|
+
#
|
95
|
+
# @example
|
96
|
+
# describe http_get(80, 'myhostname', '/') do
|
97
|
+
# its(:headers) { should include('HeaderName' => /value regex/) }
|
98
|
+
# end
|
99
|
+
#
|
100
|
+
# @api public
|
101
|
+
# @return [Hash]
|
102
|
+
def headers
|
103
|
+
@headers_hash
|
104
|
+
end
|
105
|
+
|
106
|
+
# Returns the HTTP status code, or 0 if timed out
|
107
|
+
#
|
108
|
+
# @example
|
109
|
+
# describe http_get(80, 'myhostname', '/') do
|
110
|
+
# its(:status) { should eq 200 }
|
111
|
+
# end
|
112
|
+
#
|
113
|
+
# @api public
|
114
|
+
# @return [Int]
|
115
|
+
def status
|
116
|
+
if @timed_out_status
|
117
|
+
0
|
118
|
+
else
|
119
|
+
@response_code_int
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# Returns the body/content of the HTTP response
|
124
|
+
#
|
125
|
+
# @example
|
126
|
+
# describe http_get(80, 'myhostname', '/') do
|
127
|
+
# its(:body) { should match /<html>/ }
|
128
|
+
# end
|
129
|
+
#
|
130
|
+
# @api public
|
131
|
+
# @return [String]
|
132
|
+
def body
|
133
|
+
@content_str
|
134
|
+
end
|
135
|
+
|
136
|
+
private :getpage
|
137
|
+
end
|
138
|
+
|
139
|
+
# ServerSpec Type wrapper for http_get
|
140
|
+
#
|
141
|
+
# @example
|
142
|
+
# describe http_get(80, 'myhostname', '/') do
|
143
|
+
# # tests here
|
144
|
+
# end
|
145
|
+
#
|
146
|
+
# @param port [Int] the port to connect to HTTP over
|
147
|
+
# @param host_header [String] the value to set in the 'Host' HTTP request header
|
148
|
+
# @param path [String] the URI/path to request from the server
|
149
|
+
# @param timeout_sec [Int] how many seconds to allow request to run before timing out and setting @timed_out_status to True
|
150
|
+
#
|
151
|
+
# @api public
|
152
|
+
# @return [Serverspec::Type::Http_Get]
|
153
|
+
def http_get(port, host_header, path, timeout_sec=10)
|
154
|
+
Http_Get.new(port, host_header, path, timeout_sec=timeout_sec)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
include Serverspec::Type
|
@@ -0,0 +1,161 @@
|
|
1
|
+
##############################################################################
|
2
|
+
# serverspec-extended-types - virtualenv
|
3
|
+
#
|
4
|
+
# <https://github.com/jantman/serverspec-extended-types>
|
5
|
+
#
|
6
|
+
# Copyright (C) 2015 Jason Antman <jason@jasonantman.com>
|
7
|
+
#
|
8
|
+
# Licensed under the MIT License - see LICENSE.txt
|
9
|
+
#
|
10
|
+
##############################################################################
|
11
|
+
|
12
|
+
module Serverspec::Type
|
13
|
+
class Virtualenv < Base
|
14
|
+
|
15
|
+
# Test whether this appears to be a working venv
|
16
|
+
#
|
17
|
+
# Tests performed:
|
18
|
+
# - venv_path/bin/pip executable by root?
|
19
|
+
# - venv_path/bin/python executable by root?
|
20
|
+
# - venv_path/bin/activate executable by root?
|
21
|
+
# - 'export VIRTUAL_ENV' in venv_path/bin/activate?
|
22
|
+
#
|
23
|
+
# @example
|
24
|
+
# describe virtualenv('/path/to/venv') do
|
25
|
+
# it { should be_virtualenv }
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# @api public
|
29
|
+
# @return [Boolean]
|
30
|
+
def virtualenv?
|
31
|
+
pip_path = ::File.join(@name, 'bin', 'pip')
|
32
|
+
python_path = ::File.join(@name, 'bin', 'python')
|
33
|
+
act_path = ::File.join(@name, 'bin', 'activate')
|
34
|
+
cmd = "grep -q 'export VIRTUAL_ENV' #{act_path}"
|
35
|
+
@runner.check_file_is_executable(pip_path, 'root') and
|
36
|
+
@runner.check_file_is_executable(python_path, 'root') and
|
37
|
+
@runner.check_file_is_executable(act_path, 'root') and
|
38
|
+
@runner.run_command(cmd).exit_status.to_i == 0
|
39
|
+
end
|
40
|
+
|
41
|
+
# Return the version of pip installed in the virtualenv
|
42
|
+
#
|
43
|
+
# @example
|
44
|
+
# describe virtualenv('/path/to/venv') do
|
45
|
+
# its(:pip_version) { should match /^6\.0\.6$/ }
|
46
|
+
# end
|
47
|
+
#
|
48
|
+
# @api public
|
49
|
+
# @return [String]
|
50
|
+
def pip_version
|
51
|
+
@pip_version || get_pip_version
|
52
|
+
end
|
53
|
+
|
54
|
+
# Return the version of python installed in the virtualenv
|
55
|
+
#
|
56
|
+
# @example
|
57
|
+
# describe virtualenv('/path/to/venv') do
|
58
|
+
# its(:python_version) { should match /^2\.7\.9$/ }
|
59
|
+
# end
|
60
|
+
#
|
61
|
+
# @api public
|
62
|
+
# @return [String]
|
63
|
+
def python_version
|
64
|
+
@python_version || get_python_version
|
65
|
+
end
|
66
|
+
|
67
|
+
# Return a hash of all packages present in `pip freeze` output for the venv
|
68
|
+
#
|
69
|
+
# Note that any editable packages (`-e something`) are returned as hash keys
|
70
|
+
# with an empty value
|
71
|
+
#
|
72
|
+
# @example
|
73
|
+
# describe virtualenv('/path/to/venv') do
|
74
|
+
# its(:pip_freeze) { should include('wsgiref' => '0.1.2') }
|
75
|
+
# its(:pip_freeze) { should include('requests') }
|
76
|
+
# its(:pip_freeze) { should include('pytest' => /^2\.6/) }
|
77
|
+
# its(:pip_freeze) { should include('-e git+git@github.com:jantman/someproject.git@1d8a380e3af9d081081d7ef685979200a7db4130#egg=someproject') }
|
78
|
+
# end
|
79
|
+
#
|
80
|
+
# @api public
|
81
|
+
# @return [Hash]
|
82
|
+
def pip_freeze
|
83
|
+
@pip_freeze || get_pip_freeze
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
# Get a hash for the `pip freeze` output; set @pip_freeze
|
88
|
+
#
|
89
|
+
# @api private
|
90
|
+
# @return [nil]
|
91
|
+
def get_pip_freeze()
|
92
|
+
pip_path = ::File.join(@name, 'bin', 'pip')
|
93
|
+
tmp = @runner.run_command("#{pip_path} freeze")
|
94
|
+
@pip_freeze = Hash.new()
|
95
|
+
if tmp.exit_status.to_i != 0
|
96
|
+
return @pip_freeze
|
97
|
+
end
|
98
|
+
lines = tmp.stdout.split("\n")
|
99
|
+
lines.each do |line|
|
100
|
+
line.strip!
|
101
|
+
if line =~ /^-e /
|
102
|
+
@pip_freeze[line] = ''
|
103
|
+
next
|
104
|
+
end
|
105
|
+
parts = line.split(/==/)
|
106
|
+
@pip_freeze[parts[0]] = parts[1]
|
107
|
+
end
|
108
|
+
@pip_freeze
|
109
|
+
end
|
110
|
+
|
111
|
+
private
|
112
|
+
# Get the pip version from the venv; set @pip_version
|
113
|
+
#
|
114
|
+
# @api private
|
115
|
+
# @return [nil]
|
116
|
+
def get_pip_version()
|
117
|
+
pip_path = ::File.join(@name, 'bin', 'pip')
|
118
|
+
pip_path = ::File.join(@name, 'bin', 'pip')
|
119
|
+
tmp = @runner.run_command("#{pip_path} --version")
|
120
|
+
if ( tmp.stdout =~ /^pip (\d+\S+)/ )
|
121
|
+
@pip_version = $1
|
122
|
+
else
|
123
|
+
@pip_version = ''
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
private
|
128
|
+
# Get the python version from the venv; set @python_version
|
129
|
+
#
|
130
|
+
# @api private
|
131
|
+
# @return [nil]
|
132
|
+
def get_python_version()
|
133
|
+
python_path = ::File.join(@name, 'bin', 'python')
|
134
|
+
tmp = @runner.run_command("#{python_path} --version")
|
135
|
+
if ( tmp.stderr =~ /^[Pp]ython (\d+\S+)/ )
|
136
|
+
@python_version = $1
|
137
|
+
elsif ( tmp.stdout =~ /^[Pp]ython (\d+\S+)/ )
|
138
|
+
@python_version = $1
|
139
|
+
else
|
140
|
+
@python_version = ''
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
# Serverspec Type wrapper method for Serverspec::Type::Virtualenv
|
146
|
+
#
|
147
|
+
# @example
|
148
|
+
# describe virtualenv('/path/to/venv') do
|
149
|
+
# # tests here
|
150
|
+
# end
|
151
|
+
#
|
152
|
+
# @param name [String] the absolute path to the virtualenv root
|
153
|
+
#
|
154
|
+
# @api public
|
155
|
+
# @return {Serverspec::Type::Virtualenv}
|
156
|
+
def virtualenv(name)
|
157
|
+
Virtualenv.new(name)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
include Serverspec::Type
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'serverspec_extended_types/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "serverspec-extended-types"
|
8
|
+
spec.version = ServerspecExtendedTypes::VERSION
|
9
|
+
spec.authors = ["Jason Antman"]
|
10
|
+
spec.email = ["jason@jasonantman.com"]
|
11
|
+
spec.summary = %q{A set of extended types for ServerSpec 2.x}
|
12
|
+
spec.description = %q{This gem provides some purpose-specific types for ServerSpec 2.x beyond the default ones. It is in no way associated with the ServerSpec project or developers.}
|
13
|
+
spec.homepage = "https://github.com/jantman/serverspec-extended-types"
|
14
|
+
spec.license = "MIT"
|
15
|
+
spec.files = `git ls-files -z`.split("\x0")
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
spec.add_dependency "serverspec", "~> 2"
|
20
|
+
spec.add_dependency "specinfra", "~> 2"
|
21
|
+
spec.add_dependency 'rspec', '>= 3.0'
|
22
|
+
spec.add_dependency 'faraday'
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
25
|
+
spec.add_development_dependency "rake"
|
26
|
+
spec.add_development_dependency 'simplecov'
|
27
|
+
spec.add_development_dependency 'codecov'
|
28
|
+
spec.add_development_dependency 'yard'
|
29
|
+
spec.add_development_dependency 'yardstick'
|
30
|
+
spec.add_development_dependency 'redcarpet'
|
31
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
2
|
+
|
3
|
+
require 'simplecov'
|
4
|
+
SimpleCov.start do
|
5
|
+
add_filter "/vendor/"
|
6
|
+
end
|
7
|
+
|
8
|
+
require 'codecov'
|
9
|
+
if ENV['CI']=='true'
|
10
|
+
SimpleCov.formatter = SimpleCov::Formatter::Codecov
|
11
|
+
end
|
12
|
+
|
13
|
+
require 'specinfra'
|
14
|
+
require 'rspec/mocks/standalone'
|
15
|
+
require 'rspec/its'
|
16
|
+
require 'specinfra/helper/set'
|
17
|
+
include Specinfra::Helper::Set
|
18
|
+
|
19
|
+
set :backend, :exec
|
20
|
+
|
21
|
+
set :os, :family => 'linux'
|
22
|
+
|
23
|
+
module Specinfra
|
24
|
+
module Backend
|
25
|
+
class Ssh
|
26
|
+
def run_command(cmd, opts={})
|
27
|
+
CommandResult.new :stdout => nil, :exit_status => 0
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
module GetCommand
|
34
|
+
def get_command(method, *args)
|
35
|
+
Specinfra.command.get(method, *args)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
include GetCommand
|
40
|
+
|
41
|
+
|
42
|
+
require 'serverspec_extended_types'
|
@@ -0,0 +1,189 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'serverspec_extended_types/http_get'
|
3
|
+
|
4
|
+
describe 'Serverspec::Type.bitlbee' do
|
5
|
+
it 'instantiates the class with the correct parameters' do
|
6
|
+
expect(Serverspec::Type::Bitlbee).to receive(:new).with(1, 'mynick', 'mypass', false)
|
7
|
+
bitlbee(1, 'mynick', 'mypass')
|
8
|
+
end
|
9
|
+
it 'returns the new object' do
|
10
|
+
expect(Serverspec::Type::Bitlbee).to receive(:new).and_return("foo")
|
11
|
+
expect(bitlbee(1, 'foo', 'bar')).to eq "foo"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
describe 'Serverspec::Type::Bitlbee' do
|
15
|
+
context '#initialize' do
|
16
|
+
it 'sets instance variables' do
|
17
|
+
stub_const('ENV', ENV.to_hash.merge('TARGET_HOST' => 'myhost'))
|
18
|
+
x = bitlbee(1, 'foo', 'bar')
|
19
|
+
expect(x.instance_variable_get(:@port)).to eq 1
|
20
|
+
expect(x.instance_variable_get(:@host)).to eq 'myhost'
|
21
|
+
expect(x.instance_variable_get(:@nick)).to eq 'foo'
|
22
|
+
expect(x.instance_variable_get(:@password)).to eq 'bar'
|
23
|
+
expect(x.instance_variable_get(:@connected_status)).to eq false
|
24
|
+
expect(x.instance_variable_get(:@version_str)).to eq ''
|
25
|
+
expect(x.instance_variable_get(:@timed_out_status)).to eq false
|
26
|
+
expect(x.instance_variable_get(:@started)).to eq false
|
27
|
+
expect(x.instance_variable_get(:@use_ssl)).to eq false
|
28
|
+
end
|
29
|
+
it 'sets use_ssl instance variable' do
|
30
|
+
stub_const('ENV', ENV.to_hash.merge('TARGET_HOST' => 'myhost'))
|
31
|
+
x = bitlbee(1, 'foo', 'bar', use_ssl=true)
|
32
|
+
expect(x.instance_variable_get(:@use_ssl)).to eq true
|
33
|
+
end
|
34
|
+
end
|
35
|
+
context 'start' do
|
36
|
+
it 'calls connect_ssl if use_ssl=true' do
|
37
|
+
x = bitlbee(1, 'foo', 'bar', use_ssl=true)
|
38
|
+
expect(x).to receive(:connect_ssl).once
|
39
|
+
expect(x).to_not receive(:connect)
|
40
|
+
x.start
|
41
|
+
expect(x.instance_variable_get(:@timed_out_status)).to eq false
|
42
|
+
expect(x.instance_variable_get(:@connected_status)).to eq false
|
43
|
+
expect(x.instance_variable_get(:@started)).to eq true
|
44
|
+
end
|
45
|
+
it 'calls connect if use_ssl=false' do
|
46
|
+
x = bitlbee(1, 'foo', 'bar')
|
47
|
+
expect(x).to receive(:connect).once
|
48
|
+
expect(x).to_not receive(:connect_ssl)
|
49
|
+
x.start
|
50
|
+
expect(x.instance_variable_get(:@timed_out_status)).to eq false
|
51
|
+
expect(x.instance_variable_get(:@connected_status)).to eq false
|
52
|
+
expect(x.instance_variable_get(:@started)).to eq true
|
53
|
+
end
|
54
|
+
it 'runs with a timeout' do
|
55
|
+
x = bitlbee(1, 'foo', 'bar')
|
56
|
+
expect(Timeout).to receive(:timeout).with(10)
|
57
|
+
x.start
|
58
|
+
expect(x.instance_variable_get(:@timed_out_status)).to eq false
|
59
|
+
expect(x.instance_variable_get(:@connected_status)).to eq false
|
60
|
+
expect(x.instance_variable_get(:@started)).to eq true
|
61
|
+
expect(x.timed_out?).to eq false
|
62
|
+
end
|
63
|
+
it 'sets timed_out_status on timeout' do
|
64
|
+
x = bitlbee(1, 'foo', 'bar')
|
65
|
+
expect(Timeout).to receive(:timeout).with(10).and_raise(Timeout::Error)
|
66
|
+
x.start
|
67
|
+
expect(x.instance_variable_get(:@timed_out_status)).to eq true
|
68
|
+
expect(x.instance_variable_get(:@connected_status)).to eq false
|
69
|
+
expect(x.instance_variable_get(:@started)).to eq true
|
70
|
+
expect(x.timed_out?).to eq true
|
71
|
+
expect(x.connectable?).to eq false
|
72
|
+
end
|
73
|
+
it 'sets connected_status on ECONNREFUSED' do
|
74
|
+
x = bitlbee(1, 'foo', 'bar')
|
75
|
+
expect(x).to receive(:connect).and_raise(Errno::ECONNREFUSED)
|
76
|
+
x.start
|
77
|
+
expect(x.instance_variable_get(:@timed_out_status)).to eq false
|
78
|
+
expect(x.instance_variable_get(:@connected_status)).to eq false
|
79
|
+
expect(x.instance_variable_get(:@started)).to eq true
|
80
|
+
expect(x.timed_out?).to eq false
|
81
|
+
expect(x.connectable?).to eq false
|
82
|
+
end
|
83
|
+
end
|
84
|
+
context '#connect_ssl' do
|
85
|
+
it 'calls communicate' do
|
86
|
+
stub_const('ENV', ENV.to_hash.merge('TARGET_HOST' => 'myhost'))
|
87
|
+
sock_dbl = double
|
88
|
+
expect(TCPSocket).to receive(:open).with('myhost', 1).and_return(sock_dbl)
|
89
|
+
sslctx_dbl = double
|
90
|
+
expect(OpenSSL::SSL::SSLContext).to receive(:new).and_return(sslctx_dbl)
|
91
|
+
expect(sslctx_dbl).to receive(:set_params).with(verify_mode: OpenSSL::SSL::VERIFY_NONE).ordered
|
92
|
+
sslsock_dbl = double
|
93
|
+
expect(sslsock_dbl).to receive(:sync_close=).ordered.with(true)
|
94
|
+
expect(sslsock_dbl).to receive(:connect).ordered
|
95
|
+
expect(sslsock_dbl).to receive(:puts).ordered.with("communicate")
|
96
|
+
expect(sslsock_dbl).to receive(:puts).ordered.with("QUIT :\"outta here\"\n")
|
97
|
+
expect(sslsock_dbl).to receive(:close).ordered
|
98
|
+
expect(OpenSSL::SSL::SSLSocket).to receive(:new).with(sock_dbl, sslctx_dbl).and_return(sslsock_dbl)
|
99
|
+
#expect_any_instance_of(Serverspec::Type::Bitlbee).to receive(:communicate)
|
100
|
+
x = bitlbee(1, 'foo', 'bar')
|
101
|
+
x.stub(:communicate) do
|
102
|
+
x.instance_variable_get(:@socket).puts("communicate")
|
103
|
+
end
|
104
|
+
x.connect_ssl
|
105
|
+
expect(x.instance_variable_get(:@socket)).to eq sslsock_dbl
|
106
|
+
end
|
107
|
+
end
|
108
|
+
context '#connect' do
|
109
|
+
it 'calls communicate' do
|
110
|
+
stub_const('ENV', ENV.to_hash.merge('TARGET_HOST' => 'myhost'))
|
111
|
+
sock_dbl = double
|
112
|
+
expect(TCPSocket).to receive(:open).with('myhost', 1).and_return(sock_dbl)
|
113
|
+
expect(sock_dbl).to receive(:puts).ordered.with("communicate")
|
114
|
+
expect(sock_dbl).to receive(:puts).ordered.with("QUIT :\"outta here\"\n")
|
115
|
+
expect(sock_dbl).to receive(:close).ordered
|
116
|
+
x = bitlbee(1, 'foo', 'bar')
|
117
|
+
x.stub(:communicate) do
|
118
|
+
x.instance_variable_get(:@socket).puts("communicate")
|
119
|
+
end
|
120
|
+
x.connect
|
121
|
+
expect(x.instance_variable_get(:@socket)).to eq sock_dbl
|
122
|
+
end
|
123
|
+
end
|
124
|
+
context '#communicate' do
|
125
|
+
it 'logs in' do
|
126
|
+
x = bitlbee(1, 'foo', 'bar')
|
127
|
+
sock = double
|
128
|
+
x.instance_variable_set(:@socket, sock)
|
129
|
+
x.instance_variable_set(:@started, true)
|
130
|
+
expect(sock).to receive(:puts).ordered.with("PASS bar\n")
|
131
|
+
expect(sock).to receive(:puts).ordered.with("NICK foo\n")
|
132
|
+
expect(sock).to receive(:puts).ordered.with("USER foo foo servername :TestUser\n")
|
133
|
+
expect(sock).to receive(:readpartial).ordered.with(1024).and_return("Welcome to the foo")
|
134
|
+
expect(sock).to receive(:puts).ordered.with("MODE foo +i\n")
|
135
|
+
expect(sock).to receive(:readpartial).ordered.with(1024).and_return("If you've never something something")
|
136
|
+
expect(sock).to receive(:puts).ordered.with("PRIVMSG &bitlbee :identify bar\n")
|
137
|
+
expect(sock).to receive(:readpartial).ordered.with(1024).and_return("PING servername")
|
138
|
+
expect(sock).to receive(:puts).ordered.with(":servername PONG servername :servername\n")
|
139
|
+
expect(sock).to receive(:readpartial).ordered.with(1024).and_return("MODE foo :\+i")
|
140
|
+
expect(sock).to receive(:puts).ordered.with("PRIVMSG root :\001VERSION\001\n")
|
141
|
+
expect(sock).to receive(:readpartial).ordered.with(1024).and_return("foo bar baz blam\n")
|
142
|
+
expect(sock).to receive(:readpartial).ordered.with(1024).and_return("VERSION x.y.z\n")
|
143
|
+
x.communicate
|
144
|
+
expect(x.instance_variable_get(:@connected_status)).to eq true
|
145
|
+
expect(x.version).to eq 'x.y.z'
|
146
|
+
expect(x.connectable?).to eq true
|
147
|
+
expect(x.timed_out?).to eq false
|
148
|
+
end
|
149
|
+
end
|
150
|
+
context '#timed_out?' do
|
151
|
+
it 'calls start if not started' do
|
152
|
+
x = bitlbee(1, 'foo', 'bar')
|
153
|
+
expect(x).to receive(:start).once
|
154
|
+
expect(x.timed_out?).to eq false
|
155
|
+
end
|
156
|
+
it 'doesnt call start if started' do
|
157
|
+
x = bitlbee(1, 'foo', 'bar')
|
158
|
+
x.instance_variable_set(:@started, true)
|
159
|
+
expect(x).to_not receive(:start)
|
160
|
+
expect(x.timed_out?).to eq false
|
161
|
+
end
|
162
|
+
end
|
163
|
+
context '#connectable?' do
|
164
|
+
it 'calls start if not started' do
|
165
|
+
x = bitlbee(1, 'foo', 'bar')
|
166
|
+
expect(x).to receive(:start).once
|
167
|
+
expect(x.connectable?).to eq false
|
168
|
+
end
|
169
|
+
it 'doesnt call start if started' do
|
170
|
+
x = bitlbee(1, 'foo', 'bar')
|
171
|
+
x.instance_variable_set(:@started, true)
|
172
|
+
expect(x).to_not receive(:start)
|
173
|
+
expect(x.connectable?).to eq false
|
174
|
+
end
|
175
|
+
end
|
176
|
+
context '#version?' do
|
177
|
+
it 'calls start if not started' do
|
178
|
+
x = bitlbee(1, 'foo', 'bar')
|
179
|
+
expect(x).to receive(:start).once
|
180
|
+
expect(x.version).to eq ""
|
181
|
+
end
|
182
|
+
it 'doesnt call start if started' do
|
183
|
+
x = bitlbee(1, 'foo', 'bar')
|
184
|
+
x.instance_variable_set(:@started, true)
|
185
|
+
expect(x).to_not receive(:start)
|
186
|
+
expect(x.version).to eq ""
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|