chef-handler-sns 1.2.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/README.md +116 -170
- data/lib/chef/handler/sns.rb +245 -36
- data/lib/chef/handler/sns/config.rb +168 -36
- data/lib/chef/handler/sns/config/ohai.rb +90 -27
- data/lib/chef/handler/sns/version.rb +29 -2
- data/test/helper.rb +23 -2
- data/test/test_chef_handler_sns.rb +233 -141
- data/test/test_chef_handler_sns_config.rb +89 -71
- data/test/test_chef_handler_sns_config_ohai.rb +57 -47
- metadata +100 -43
@@ -1,5 +1,6 @@
|
|
1
1
|
#
|
2
|
-
# Author:: Xabier de Zuazo (<xabier@
|
2
|
+
# Author:: Xabier de Zuazo (<xabier@zuazo.org>)
|
3
|
+
# Copyright:: Copyright (c) 2015 Xabier de Zuazo
|
3
4
|
# Copyright:: Copyright (c) 2014 Onddo Labs, SL.
|
4
5
|
# License:: Apache License, Version 2.0
|
5
6
|
#
|
@@ -20,46 +21,108 @@ class Chef
|
|
20
21
|
class Handler
|
21
22
|
class Sns < ::Chef::Handler
|
22
23
|
module Config
|
24
|
+
#
|
25
|
+
# Gets Chef Handler SNS default configuration from
|
26
|
+
# [Ohai](https://docs.chef.io/ohai.html) information.
|
27
|
+
#
|
23
28
|
class Ohai
|
29
|
+
#
|
30
|
+
# AWS region name.
|
31
|
+
#
|
32
|
+
# Not used, read from the topic ARN.
|
33
|
+
#
|
34
|
+
# @return [String] Region.
|
35
|
+
#
|
36
|
+
attr_reader :region
|
24
37
|
|
38
|
+
#
|
39
|
+
# AWS access key.
|
40
|
+
#
|
41
|
+
# @return [String] Access key.
|
42
|
+
#
|
43
|
+
attr_reader :access_key
|
44
|
+
|
45
|
+
#
|
46
|
+
# AWS secret key.
|
47
|
+
#
|
48
|
+
# @return [String] Secret key.
|
49
|
+
#
|
50
|
+
attr_reader :secret_key
|
51
|
+
|
52
|
+
#
|
53
|
+
# AWS token.
|
54
|
+
#
|
55
|
+
# @return [String] token.
|
56
|
+
#
|
57
|
+
attr_reader :token
|
58
|
+
|
59
|
+
#
|
60
|
+
# Constructs a {Chef::Handler::Sns::Config::Ohai} object.
|
61
|
+
#
|
62
|
+
# @param node [Chef::Node] Node object to read Ohai information from.
|
63
|
+
#
|
64
|
+
# @api public
|
65
|
+
#
|
25
66
|
def initialize(node)
|
26
67
|
read_config(node)
|
27
68
|
end
|
28
69
|
|
29
|
-
|
30
|
-
@region
|
31
|
-
end
|
32
|
-
|
33
|
-
def access_key
|
34
|
-
@access_key
|
35
|
-
end
|
70
|
+
protected
|
36
71
|
|
37
|
-
|
38
|
-
|
72
|
+
#
|
73
|
+
# Reads AWS region information from Ohai.
|
74
|
+
#
|
75
|
+
# Old code. This is currently not used. We are reading region
|
76
|
+
# information from Topic ARN.
|
77
|
+
#
|
78
|
+
# @param ec2 [Hash] These are attributes below `node['ec2']`.
|
79
|
+
#
|
80
|
+
# @return void
|
81
|
+
#
|
82
|
+
# @api private
|
83
|
+
#
|
84
|
+
def read_region_config(ec2)
|
85
|
+
return unless ec2.attribute?('placement_availability_zone') &&
|
86
|
+
ec2['placement_availability_zone'].is_a?(String)
|
87
|
+
@region = ec2['placement_availability_zone'].chop
|
39
88
|
end
|
40
89
|
|
41
|
-
|
42
|
-
|
90
|
+
#
|
91
|
+
# Reads the IAM credentials from Ohai.
|
92
|
+
#
|
93
|
+
# @param ec2 [Hash] These are attributes below `node['ec2']`.
|
94
|
+
#
|
95
|
+
# @return void
|
96
|
+
#
|
97
|
+
# @api private
|
98
|
+
#
|
99
|
+
def read_iam_config(ec2)
|
100
|
+
return unless ec2.attribute?('iam') &&
|
101
|
+
ec2['iam'].attribute?('security-credentials')
|
102
|
+
_iam_role, credentials =
|
103
|
+
ec2['iam']['security-credentials'].to_hash.first
|
104
|
+
return if credentials.nil?
|
105
|
+
@access_key = credentials['AccessKeyId']
|
106
|
+
@secret_key = credentials['SecretAccessKey']
|
107
|
+
@token = credentials['Token']
|
43
108
|
end
|
44
109
|
|
45
|
-
|
46
|
-
|
110
|
+
#
|
111
|
+
# Reads configuration information from Ohai.
|
112
|
+
#
|
113
|
+
# Reads both region information and IAM credentials.
|
114
|
+
#
|
115
|
+
# @param node [Chef::Node] Node object to read information from.
|
116
|
+
#
|
117
|
+
# @return void
|
118
|
+
#
|
119
|
+
# @api private
|
120
|
+
#
|
47
121
|
def read_config(node)
|
48
122
|
return unless node.attribute?('ec2')
|
49
|
-
|
50
|
-
|
51
|
-
@region = node.ec2.placement_availability_zone.chop
|
52
|
-
end
|
53
|
-
if node.ec2.attribute?('iam') and node.ec2.iam.attribute?('security-credentials')
|
54
|
-
iam_role, credentials = node.ec2.iam['security-credentials'].first
|
55
|
-
unless credentials.nil?
|
56
|
-
@access_key = credentials['AccessKeyId']
|
57
|
-
@secret_key = credentials['SecretAccessKey']
|
58
|
-
@token = credentials['Token']
|
59
|
-
end
|
60
|
-
end
|
123
|
+
read_region_config(node['ec2'])
|
124
|
+
read_iam_config(node['ec2'])
|
61
125
|
end
|
62
|
-
|
63
126
|
end
|
64
127
|
end
|
65
128
|
end
|
@@ -1,9 +1,36 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Xabier de Zuazo (<xabier@zuazo.org>)
|
3
|
+
# Copyright:: Copyright (c) 2015 Xabier de Zuazo
|
4
|
+
# Copyright:: Copyright (c) 2014 Onddo Labs, SL.
|
5
|
+
# License:: Apache License, Version 2.0
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
#
|
1
19
|
|
2
20
|
class Chef
|
3
21
|
class Handler
|
22
|
+
#
|
23
|
+
# Chef Handler SNS main class.
|
24
|
+
#
|
25
|
+
# A simple Chef report handler that reports status of a Chef run through
|
26
|
+
# [Amazon SNS](http://aws.amazon.com/sns/),
|
27
|
+
# [including IAM roles support](#usage-with-amazon-iam-roles).
|
28
|
+
#
|
4
29
|
class Sns < ::Chef::Handler
|
5
|
-
|
30
|
+
#
|
31
|
+
# chef-handler-sns Ruby Gem version.
|
32
|
+
#
|
33
|
+
VERSION = '2.0.0'
|
6
34
|
end
|
7
35
|
end
|
8
36
|
end
|
9
|
-
|
data/test/helper.rb
CHANGED
@@ -1,14 +1,35 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Xabier de Zuazo (<xabier@zuazo.org>)
|
3
|
+
# Copyright:: Copyright (c) 2015 Xabier de Zuazo
|
4
|
+
# Copyright:: Copyright (c) 2014 Onddo Labs, SL.
|
5
|
+
# License:: Apache License, Version 2.0
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
#
|
19
|
+
|
1
20
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
21
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
22
|
|
4
23
|
require 'simplecov'
|
5
|
-
if ENV['TRAVIS']
|
24
|
+
if ENV['TRAVIS'] && RUBY_VERSION >= '2.1.0'
|
6
25
|
require 'coveralls'
|
7
26
|
SimpleCov.formatter = Coveralls::SimpleCov::Formatter
|
8
27
|
end
|
9
28
|
SimpleCov.start
|
10
29
|
|
11
|
-
gem 'minitest' #
|
30
|
+
gem 'minitest' # Ensures you're using the gem, and not the built in MT
|
12
31
|
require 'minitest/autorun'
|
32
|
+
require 'minitest/stub_const'
|
13
33
|
require 'mocha/setup'
|
14
34
|
require 'chef/handler/sns'
|
35
|
+
require 'should_not/minitest'
|
@@ -1,211 +1,303 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Xabier de Zuazo (<xabier@zuazo.org>)
|
3
|
+
# Copyright:: Copyright (c) 2015 Xabier de Zuazo
|
4
|
+
# Copyright:: Copyright (c) 2014 Onddo Labs, SL.
|
5
|
+
# License:: Apache License, Version 2.0
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
#
|
19
|
+
|
1
20
|
require 'helper'
|
2
21
|
require 'chef/node'
|
3
22
|
require 'chef/run_status'
|
4
23
|
|
5
|
-
|
6
|
-
|
24
|
+
module Aws
|
25
|
+
class FakeSNS
|
26
|
+
attr_reader :sns_new
|
27
|
+
|
28
|
+
def initialize(*_args)
|
29
|
+
@sns_new = true
|
30
|
+
self
|
31
|
+
end
|
7
32
|
|
8
|
-
|
9
|
-
|
10
|
-
|
33
|
+
def publish(*_args)
|
34
|
+
true
|
35
|
+
end
|
36
|
+
|
37
|
+
def config
|
38
|
+
@config ||= Seahorse::Client::Configuration.new
|
39
|
+
end
|
11
40
|
end
|
41
|
+
end
|
12
42
|
|
13
|
-
|
43
|
+
describe Chef::Handler::Sns do
|
44
|
+
let(:data_dir) { ::File.join(::File.dirname(__FILE__), 'data') }
|
45
|
+
let(:node) do
|
46
|
+
node = Chef::Node.new
|
47
|
+
node.name('test')
|
48
|
+
node
|
49
|
+
end
|
50
|
+
let(:run_status) do
|
51
|
+
run_status =
|
52
|
+
if Gem.loaded_specs['chef'].version > Gem::Version.new('0.12.0')
|
53
|
+
Chef::RunStatus.new(node, {})
|
54
|
+
else
|
55
|
+
Chef::RunStatus.new(node)
|
56
|
+
end
|
57
|
+
|
58
|
+
run_status.start_clock
|
59
|
+
run_status.stop_clock
|
60
|
+
run_status
|
61
|
+
end
|
62
|
+
let(:config) do
|
14
63
|
{
|
15
|
-
|
64
|
+
access_key: '***AMAZON-KEY***',
|
65
|
+
secret_key: '***AMAZON-SECRET***',
|
66
|
+
topic_arn: 'arn:aws:sns:***'
|
16
67
|
}
|
17
68
|
end
|
69
|
+
let(:sns_handler) { Chef::Handler::Sns.new(config) }
|
70
|
+
let(:fake_sns) do
|
71
|
+
Aws::FakeSNS.new(
|
72
|
+
access_key_id: config[:access_key],
|
73
|
+
secret_access_key: config[:secret_key],
|
74
|
+
region: config[:region],
|
75
|
+
logger: Chef::Log
|
76
|
+
)
|
77
|
+
end
|
78
|
+
before do
|
79
|
+
Aws::SNS::Client.stubs(:new).returns(fake_sns)
|
18
80
|
|
19
|
-
|
81
|
+
Chef::Handler::Sns.any_instance.stubs(:node).returns(node)
|
82
|
+
end
|
20
83
|
|
21
|
-
|
84
|
+
it 'reads the configuration options on initialization' do
|
85
|
+
assert_equal config[:access_key], sns_handler.access_key
|
86
|
+
assert_equal config[:secret_key], sns_handler.secret_key
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'is able to change configuration options using method calls' do
|
90
|
+
sns_handler = Chef::Handler::Sns.new
|
91
|
+
sns_handler.access_key(config[:access_key])
|
92
|
+
sns_handler.secret_key(config[:secret_key])
|
22
93
|
|
23
|
-
|
24
|
-
|
94
|
+
assert_equal config[:access_key], sns_handler.access_key
|
95
|
+
assert_equal config[:secret_key], sns_handler.secret_key
|
25
96
|
end
|
26
97
|
|
27
|
-
|
28
|
-
|
98
|
+
it 'tries to send a SNS message when properly configured' do
|
99
|
+
fake_sns.expects(:publish).once
|
100
|
+
|
101
|
+
sns_handler.run_report_safely(run_status)
|
29
102
|
end
|
30
103
|
|
31
|
-
|
104
|
+
it 'creates an Aws::SNS object' do
|
105
|
+
sns_handler.run_report_safely(run_status)
|
32
106
|
|
33
|
-
|
34
|
-
|
35
|
-
AWS::SNS::Topic.any_instance.stubs(:publish).returns(true)
|
36
|
-
# avoid File.read("endpoints.json")
|
37
|
-
AWS::Core::Endpoints.stubs(:endpoints).returns({
|
38
|
-
'regions' => {
|
39
|
-
'us-east-1' => {
|
40
|
-
'sns' => {
|
41
|
-
'http' => true,
|
42
|
-
'https' => true,
|
43
|
-
'hostname' => 'sns.us-east-1.amazonaws.com',
|
44
|
-
}
|
45
|
-
}
|
46
|
-
}
|
47
|
-
})
|
48
|
-
|
49
|
-
@node = Chef::Node.new
|
50
|
-
@node.name('test')
|
51
|
-
Chef::Handler::Sns.any_instance.stubs(:node).returns(@node)
|
52
|
-
Chef::Handler::FakeSns.any_instance.stubs(:node).returns(@node)
|
53
|
-
|
54
|
-
@run_status = if Gem.loaded_specs['chef'].version > Gem::Version.new('0.12.0')
|
55
|
-
Chef::RunStatus.new(@node, {})
|
56
|
-
else
|
57
|
-
Chef::RunStatus.new(@node)
|
58
|
-
end
|
107
|
+
assert_equal true, fake_sns.sns_new
|
108
|
+
end
|
59
109
|
|
60
|
-
|
61
|
-
|
110
|
+
it 'gets the AWS region from the ARN' do
|
111
|
+
sns_handler = Chef::Handler::Sns.new
|
112
|
+
sns_handler.topic_arn('arn:aws:sns:eu-west-1:1234:MyTopic')
|
62
113
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
114
|
+
assert_equal 'eu-west-1', sns_handler.region
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'does not detect AWS region automatically when manually set' do
|
118
|
+
config[:region] = 'us-east-1'
|
119
|
+
sns_handler = Chef::Handler::Sns.new(config)
|
120
|
+
sns_handler.topic_arn('arn:aws:sns:eu-west-1:1234:MyTopic')
|
121
|
+
sns_handler.run_report_safely(run_status)
|
122
|
+
|
123
|
+
assert_equal 'us-east-1', sns_handler.region
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'is able to generate the default subject in chef-client' do
|
127
|
+
Chef::Config[:solo] = false
|
128
|
+
sns_handler.run_report_unsafe(run_status)
|
129
|
+
|
130
|
+
assert_equal 'Chef Client success in test', sns_handler.send(:sns_subject)
|
68
131
|
end
|
69
132
|
|
70
|
-
it '
|
71
|
-
|
72
|
-
|
73
|
-
|
133
|
+
it 'is able to generate the default subject in chef-solo' do
|
134
|
+
Chef::Config[:solo] = true
|
135
|
+
sns_handler.run_report_unsafe(run_status)
|
136
|
+
|
137
|
+
assert_equal 'Chef Solo success in test', sns_handler.send(:sns_subject)
|
74
138
|
end
|
75
139
|
|
76
|
-
it '
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
assert_equal
|
81
|
-
assert_equal @sns_handler.secret_key, @config[:secret_key]
|
140
|
+
it 'uses the configured subject when set' do
|
141
|
+
config[:subject] = 'My Subject'
|
142
|
+
sns_handler.run_report_unsafe(run_status)
|
143
|
+
|
144
|
+
assert_equal 'My Subject', sns_handler.send(:sns_subject)
|
82
145
|
end
|
83
146
|
|
84
|
-
it '
|
85
|
-
|
86
|
-
AWS::SNS::Topic.any_instance.expects(:publish).once
|
147
|
+
it 'is able to generate the default message body' do
|
148
|
+
sns_handler.run_report_unsafe(run_status)
|
87
149
|
|
88
|
-
|
150
|
+
sns_handler.send(:sns_body).must_match Regexp.new('Node Name: test')
|
89
151
|
end
|
90
152
|
|
91
|
-
it '
|
92
|
-
|
93
|
-
fake_sns = AWS::FakeSNS.new({
|
94
|
-
:access_key_id => @config[:access_key],
|
95
|
-
:secret_access_key => @config[:secret_key],
|
96
|
-
:logger => Chef::Log
|
97
|
-
})
|
98
|
-
AWS::SNS.stubs(:new).returns(fake_sns)
|
99
|
-
@sns_handler.run_report_safely(@run_status)
|
153
|
+
it 'throws an exception when the body template file does not exist' do
|
154
|
+
config[:body_template] = '/tmp/nonexistent-template.erb'
|
100
155
|
|
101
|
-
|
156
|
+
assert_raises(Chef::Exceptions::ValidationFailed) do
|
157
|
+
sns_handler.run_report_unsafe(run_status)
|
158
|
+
end
|
102
159
|
end
|
103
160
|
|
104
|
-
it '
|
105
|
-
|
106
|
-
|
107
|
-
|
161
|
+
it 'is able to generate the body template when configured as an '\
|
162
|
+
'option' do
|
163
|
+
body_msg = 'My Template'
|
164
|
+
config[:body_template] = '/tmp/existing-template.erb'
|
165
|
+
::File.stubs(:exist?).with(config[:body_template]).returns(true)
|
166
|
+
IO.stubs(:read).with(config[:body_template]).returns(body_msg)
|
167
|
+
|
168
|
+
sns_handler.run_report_unsafe(run_status)
|
108
169
|
|
109
|
-
|
170
|
+
assert_equal body_msg, sns_handler.send(:sns_body)
|
110
171
|
end
|
111
172
|
|
112
|
-
it '
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
@sns_handler.run_report_safely(@run_status)
|
173
|
+
it 'is able to read body templates in UTF-8' do
|
174
|
+
config[:body_template] = ::File.join(data_dir, 'body_utf8.txt')
|
175
|
+
|
176
|
+
sns_handler.run_report_unsafe(run_status)
|
117
177
|
|
118
|
-
|
178
|
+
assert_includes sns_handler.send(:sns_body), 'abc'
|
119
179
|
end
|
120
180
|
|
121
|
-
it '
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
@fake_sns_handler.run_report_unsafe(@run_status)
|
181
|
+
it 'is able to read body templates in latin' do
|
182
|
+
config[:body_template] = ::File.join(data_dir, 'body_latin.txt')
|
183
|
+
|
184
|
+
sns_handler.run_report_unsafe(run_status)
|
126
185
|
|
127
|
-
|
186
|
+
assert_includes sns_handler.send(:sns_body), 'abc'
|
128
187
|
end
|
129
188
|
|
130
|
-
it '
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
189
|
+
it 'replaces body characters with wrong encoding' do
|
190
|
+
config[:body_template] = ::File.join(data_dir, 'body_latin.txt')
|
191
|
+
|
192
|
+
sns_handler.run_report_unsafe(run_status)
|
193
|
+
|
194
|
+
assert_includes sns_handler.send(:sns_body), '???'
|
195
|
+
end
|
196
|
+
|
197
|
+
it 'does not cut short bodies' do
|
198
|
+
body_msg = 'A' * 262_144
|
199
|
+
config[:body_template] = '/tmp/existing-template.erb'
|
200
|
+
::File.stubs(:exist?).with(config[:body_template]).returns(true)
|
201
|
+
IO.stubs(:read).with(config[:body_template]).returns(body_msg)
|
135
202
|
|
136
|
-
assert_equal
|
203
|
+
assert_equal body_msg, sns_handler.send(:sns_body)
|
137
204
|
end
|
138
205
|
|
139
|
-
it '
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
206
|
+
it 'cuts long bodies' do
|
207
|
+
body_msg = 'A' * 262_144
|
208
|
+
config[:body_template] = '/tmp/existing-template.erb'
|
209
|
+
::File.stubs(:exist?).with(config[:body_template]).returns(true)
|
210
|
+
IO.stubs(:read).with(config[:body_template]).returns("#{body_msg}A")
|
144
211
|
|
145
|
-
assert_equal
|
212
|
+
assert_equal body_msg, sns_handler.send(:sns_body)
|
146
213
|
end
|
147
214
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
215
|
+
if RUBY_VERSION >= '2.1.0'
|
216
|
+
it 'does not cut short bodies with utf8' do
|
217
|
+
body_msg = 'A' * 262_141 + "\u2014"
|
218
|
+
config[:body_template] = '/tmp/existing-template.erb'
|
219
|
+
::File.stubs(:exist?).with(config[:body_template]).returns(true)
|
220
|
+
IO.stubs(:read).with(config[:body_template]).returns(body_msg)
|
221
|
+
|
222
|
+
assert_equal body_msg, sns_handler.send(:sns_body)
|
223
|
+
end
|
224
|
+
|
225
|
+
it 'cuts long bodies with utf8' do
|
226
|
+
body_msg = 'A' * 262_142
|
227
|
+
config[:body_template] = '/tmp/existing-template.erb'
|
228
|
+
::File.stubs(:exist?).with(config[:body_template]).returns(true)
|
229
|
+
IO.stubs(:read).with(config[:body_template]).returns("#{body_msg}\u2014")
|
230
|
+
|
231
|
+
assert_equal body_msg, sns_handler.send(:sns_body)
|
232
|
+
end
|
233
|
+
|
234
|
+
# Coverage to 100%: Run code for Ruby 2.0
|
235
|
+
it 'encodes utf8 chars as binary on Ruby < 2.1' do
|
236
|
+
Object.stub_const(:RUBY_VERSION, '2.0.0') do
|
237
|
+
body_msg = 'A' * 4
|
238
|
+
config[:body_template] = '/tmp/existing-template.erb'
|
239
|
+
::File.stubs(:exist?).with(config[:body_template]).returns(true)
|
240
|
+
IO.stubs(:read).with(config[:body_template]).returns(body_msg)
|
152
241
|
|
153
|
-
|
242
|
+
assert_equal body_msg, sns_handler.send(:sns_body)
|
243
|
+
end
|
244
|
+
end
|
154
245
|
end
|
155
246
|
|
156
|
-
it '
|
157
|
-
|
158
|
-
@sns_handler = Chef::Handler::Sns.new(@config)
|
247
|
+
it 'is able to use subject with wrong encoding' do
|
248
|
+
config[:subject] = ::IO.read(::File.join(data_dir, 'subject_utf8.txt'))
|
159
249
|
|
160
|
-
|
250
|
+
sns_handler.run_report_unsafe(run_status)
|
251
|
+
|
252
|
+
assert_includes sns_handler.send(:sns_subject), 'abc'
|
253
|
+
assert_includes sns_handler.send(:sns_subject), 'xyz'
|
161
254
|
end
|
162
255
|
|
163
|
-
it '
|
164
|
-
|
165
|
-
@config[:body_template] = '/tmp/existing-template.erb'
|
166
|
-
::File.stubs(:exists?).with(@config[:body_template]).returns(true)
|
167
|
-
IO.stubs(:read).with(@config[:body_template]).returns(body_msg)
|
256
|
+
it 'replaces subject characters with wrong encoding' do
|
257
|
+
config[:subject] = ::IO.read(::File.join(data_dir, 'subject_utf8.txt'))
|
168
258
|
|
169
|
-
|
170
|
-
AWS::SNS.stubs(:new).returns(fake_sns)
|
171
|
-
@fake_sns_handler = Chef::Handler::FakeSns.new(@config)
|
172
|
-
Chef::Handler::FakeSns.any_instance.stubs(:node).returns(@node)
|
173
|
-
@fake_sns_handler.run_report_unsafe(@run_status)
|
259
|
+
sns_handler.run_report_unsafe(run_status)
|
174
260
|
|
175
|
-
|
261
|
+
assert_includes sns_handler.send(:sns_subject), '???'
|
176
262
|
end
|
177
263
|
|
178
|
-
it '
|
179
|
-
|
180
|
-
AWS::SNS::Topic.any_instance.expects(:publish).once
|
264
|
+
it 'cuts long subjects' do
|
265
|
+
config[:subject] = 'A' * 200
|
181
266
|
|
182
|
-
|
267
|
+
sns_handler.run_report_unsafe(run_status)
|
268
|
+
|
269
|
+
assert_equal 'A' * 100, sns_handler.send(:sns_subject)
|
183
270
|
end
|
184
271
|
|
185
|
-
it '
|
186
|
-
|
187
|
-
@config[:filter_opsworks_activity] = ['deploy', 'setup']
|
272
|
+
it 'publishes messages if node["opsworks"]["activity"] does not exist' do
|
273
|
+
fake_sns.expects(:publish).once
|
188
274
|
|
189
|
-
|
190
|
-
AWS::SNS::Topic.any_instance.expects(:publish).once
|
191
|
-
@sns_handler.run_report_safely(@run_status)
|
275
|
+
sns_handler.run_report_safely(run_status)
|
192
276
|
end
|
193
277
|
|
194
|
-
it '
|
195
|
-
|
196
|
-
|
278
|
+
it 'publishes messages if node["opsworks"]["activity"] matches allowed '\
|
279
|
+
'acvities' do
|
280
|
+
node.set['opsworks']['activity'] = 'deploy'
|
281
|
+
config[:filter_opsworks_activity] = %w(deploy setup)
|
197
282
|
|
198
|
-
|
199
|
-
|
200
|
-
@sns_handler.run_report_safely(@run_status)
|
283
|
+
fake_sns.expects(:publish).once
|
284
|
+
sns_handler.run_report_safely(run_status)
|
201
285
|
end
|
202
286
|
|
203
|
-
it '
|
204
|
-
|
287
|
+
it 'does not publish messages if node["opsworks"]["activity"] differs '\
|
288
|
+
'from allowed acvities' do
|
289
|
+
node.set['opsworks']['activity'] = 'configure'
|
290
|
+
config[:filter_opsworks_activity] = %w(deploy setup)
|
205
291
|
|
206
|
-
|
207
|
-
|
208
|
-
@sns_handler.run_report_safely(@run_status)
|
292
|
+
fake_sns.expects(:publish).never
|
293
|
+
sns_handler.run_report_safely(run_status)
|
209
294
|
end
|
210
295
|
|
296
|
+
it 'does not publish messages if node["opsworks"]["activity"] is set, '\
|
297
|
+
'but the node attribute is missing' do
|
298
|
+
config[:filter_opsworks_activity] = %w(deploy setup)
|
299
|
+
|
300
|
+
fake_sns.expects(:publish).never
|
301
|
+
sns_handler.run_report_safely(run_status)
|
302
|
+
end
|
211
303
|
end
|