qurd 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.
Files changed (74) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.ruby-version +1 -0
  4. data/Gemfile +5 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +367 -0
  7. data/Rakefile +9 -0
  8. data/bin/qurd +10 -0
  9. data/lib/hash.rb +6 -0
  10. data/lib/qurd.rb +49 -0
  11. data/lib/qurd/action.rb +92 -0
  12. data/lib/qurd/action/chef.rb +128 -0
  13. data/lib/qurd/action/dummy.rb +27 -0
  14. data/lib/qurd/action/route53.rb +168 -0
  15. data/lib/qurd/configuration.rb +182 -0
  16. data/lib/qurd/listener.rb +207 -0
  17. data/lib/qurd/message.rb +231 -0
  18. data/lib/qurd/mixins.rb +8 -0
  19. data/lib/qurd/mixins/aws_clients.rb +37 -0
  20. data/lib/qurd/mixins/configuration.rb +29 -0
  21. data/lib/qurd/mixins/configuration_helpers.rb +79 -0
  22. data/lib/qurd/processor.rb +97 -0
  23. data/lib/qurd/version.rb +5 -0
  24. data/lib/string.rb +12 -0
  25. data/qurd.gemspec +32 -0
  26. data/test/action_test.rb +115 -0
  27. data/test/chef_test.rb +206 -0
  28. data/test/configuration_test.rb +333 -0
  29. data/test/dummy_action_test.rb +51 -0
  30. data/test/inputs/foo.pem +27 -0
  31. data/test/inputs/knife.rb +9 -0
  32. data/test/inputs/qurd.yml +32 -0
  33. data/test/inputs/qurd_chef.yml +35 -0
  34. data/test/inputs/qurd_chef_route53.yml +43 -0
  35. data/test/inputs/qurd_route53.yml +39 -0
  36. data/test/inputs/qurd_route53_wrong.yml +37 -0
  37. data/test/inputs/validator.pem +27 -0
  38. data/test/listener_test.rb +135 -0
  39. data/test/message_test.rb +187 -0
  40. data/test/mixin_aws_clients_test.rb +28 -0
  41. data/test/mixin_configuration_test.rb +36 -0
  42. data/test/processor_test.rb +41 -0
  43. data/test/responses/aws/ec2-describe-instances-0.xml +2 -0
  44. data/test/responses/aws/ec2-describe-instances-1.xml +127 -0
  45. data/test/responses/aws/error-response.xml +1 -0
  46. data/test/responses/aws/route53-change-resource-record-sets.xml +2 -0
  47. data/test/responses/aws/route53-list-hosted-zones-by-name-0.xml +3 -0
  48. data/test/responses/aws/route53-list-hosted-zones-by-name-1.xml +4 -0
  49. data/test/responses/aws/route53-list-hosted-zones-by-name-n.xml +5 -0
  50. data/test/responses/aws/route53-list-resource-record-sets-0.xml +2 -0
  51. data/test/responses/aws/route53-list-resource-record-sets-1.xml +4 -0
  52. data/test/responses/aws/route53-list-resource-record-sets-n.xml +6 -0
  53. data/test/responses/aws/sqs-list-queues-0.xml +1 -0
  54. data/test/responses/aws/sqs-list-queues-n.xml +4 -0
  55. data/test/responses/aws/sqs-receive-message-1-launch.xml +6 -0
  56. data/test/responses/aws/sqs-receive-message-1-launch_error.xml +6 -0
  57. data/test/responses/aws/sqs-receive-message-1-other.xml +12 -0
  58. data/test/responses/aws/sqs-receive-message-1-terminate.xml +6 -0
  59. data/test/responses/aws/sqs-receive-message-1-terminate_error.xml +6 -0
  60. data/test/responses/aws/sqs-receive-message-1-test.xml +12 -0
  61. data/test/responses/aws/sqs-set-queue-attributes.xml +1 -0
  62. data/test/responses/aws/sts-assume-role.xml +17 -0
  63. data/test/responses/chef/search-client-name-0.json +6 -0
  64. data/test/responses/chef/search-client-name-1.json +7 -0
  65. data/test/responses/chef/search-client-name-n.json +8 -0
  66. data/test/responses/chef/search-node-instance-0.json +5 -0
  67. data/test/responses/chef/search-node-instance-1.json +784 -0
  68. data/test/responses/chef/search-node-instance-n.json +1565 -0
  69. data/test/responses/ec2/latest-meta-data-iam-security-credentials-client.txt +9 -0
  70. data/test/responses/ec2/latest-meta-data-iam-security-credentials.txt +1 -0
  71. data/test/route53_test.rb +231 -0
  72. data/test/support/web_mock_stubs.rb +109 -0
  73. data/test/test_helper.rb +10 -0
  74. metadata +307 -0
@@ -0,0 +1,35 @@
1
+ ---
2
+ dry_run: false
3
+ daemonize: false
4
+ pid_file: tmp/qurd.pid
5
+ wait_time: 20
6
+ visibility_timeout: 600
7
+ log_file: tmp/qurd.log
8
+ log_level: debug
9
+ aws_credentials:
10
+ - name: test
11
+ type: shared_credentials
12
+ options:
13
+ profile_name: prod-west
14
+ auto_scaling_queues:
15
+ staging:
16
+ credentials: test
17
+ region: us-west-2
18
+ queues:
19
+ - "/ScalingNotificationsQueue/"
20
+ chef_configuration: "test/inputs/knife.rb"
21
+
22
+ actions:
23
+ launch:
24
+ - "Qurd::Action::Dummy"
25
+ launch_error:
26
+ - "Qurd::Action::Dummy"
27
+ terminate:
28
+ - "Qurd::Action::Dummy"
29
+ - "Qurd::Action::Chef"
30
+ terminate_error:
31
+ - "Qurd::Action::Dummy"
32
+ test:
33
+ - "Qurd::Action::Dummy"
34
+ - "Qurd::Action::Chef"
35
+
@@ -0,0 +1,43 @@
1
+ ---
2
+ dry_run: false
3
+ daemonize: false
4
+ pid_file: tmp/qurd.pid
5
+ wait_time: 20
6
+ visibility_timeout: 600
7
+ log_file: tmp/qurd.log
8
+ log_level: debug
9
+
10
+ aws_credentials:
11
+ - name: test
12
+ type: shared_credentials
13
+ options:
14
+ profile_name: prod-west
15
+ auto_scaling_queues:
16
+ staging:
17
+ credentials: test
18
+ region: us-west-2
19
+ queues:
20
+ - "/ScalingNotificationsQueue/"
21
+
22
+ chef_configuration: "test/inputs/knife.rb"
23
+
24
+ route53:
25
+ staging:
26
+ hosted_zone: "staging.example.com."
27
+
28
+ actions:
29
+ launch:
30
+ - "Qurd::Action::Dummy"
31
+ launch_error:
32
+ - "Qurd::Action::Dummy"
33
+ terminate:
34
+ - "Qurd::Action::Dummy"
35
+ - "Qurd::Action::Chef"
36
+ - "Qurd::Action::Route53"
37
+ terminate_error:
38
+ - "Qurd::Action::Dummy"
39
+ test:
40
+ - "Qurd::Action::Dummy"
41
+ - "Qurd::Action::Chef"
42
+ - "Qurd::Action::Route53"
43
+
@@ -0,0 +1,39 @@
1
+ ---
2
+ dry_run: false
3
+ daemonize: false
4
+ pid_file: tmp/qurd.pid
5
+ wait_time: 20
6
+ visibility_timeout: 600
7
+ log_file: tmp/qurd.log
8
+ log_level: debug
9
+ aws_credentials:
10
+ - name: test
11
+ type: credentials
12
+ options:
13
+ access_key_id: bar
14
+ secret_access_key: foo
15
+ auto_scaling_queues:
16
+ staging:
17
+ credentials: test
18
+ region: us-west-2
19
+ queues:
20
+ - "/ScalingNotificationsQueue/"
21
+
22
+ route53:
23
+ staging:
24
+ hosted_zone: "staging.example.com."
25
+
26
+ actions:
27
+ launch:
28
+ - "Qurd::Action::Dummy"
29
+ launch_error:
30
+ - "Qurd::Action::Dummy"
31
+ terminate:
32
+ - "Qurd::Action::Dummy"
33
+ - "Qurd::Action::Route53"
34
+ terminate_error:
35
+ - "Qurd::Action::Dummy"
36
+ test:
37
+ - "Qurd::Action::Dummy"
38
+ - "Qurd::Action::Route53"
39
+
@@ -0,0 +1,37 @@
1
+ ---
2
+ dry_run: false
3
+ daemonize: false
4
+ pid_file: tmp/qurd.pid
5
+ wait_time: 20
6
+ visibility_timeout: 600
7
+ log_file: tmp/qurd.log
8
+ log_level: debug
9
+ aws_credentials:
10
+ - name: test
11
+ type: credentials
12
+ options:
13
+ access_key_id: bar
14
+ secret_access_key: foo
15
+ auto_scaling_queues:
16
+ staging:
17
+ credentials: test
18
+ region: us-west-2
19
+ queues:
20
+ - "/ScalingNotificationsQueue/"
21
+
22
+ route53:
23
+
24
+ actions:
25
+ launch:
26
+ - "Qurd::Action::Dummy"
27
+ launch_error:
28
+ - "Qurd::Action::Dummy"
29
+ terminate:
30
+ - "Qurd::Action::Dummy"
31
+ - "Qurd::Action::Route53"
32
+ terminate_error:
33
+ - "Qurd::Action::Dummy"
34
+ test:
35
+ - "Qurd::Action::Dummy"
36
+ - "Qurd::Action::Route53"
37
+
@@ -0,0 +1,27 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ MIIEpAIBAAKCAQEAyCm6JNqwyUL+E0ohhgI9+EFQ2++pZVd0+bMpgMHg6yCT1D66
3
+ GkLRBuNqcExFRvhzPDlSAXmWC7nike5VXWexJdFEQIDJ0KdyiJBLJGCIDYfJEFfA
4
+ dKhQPysT+fcLjMYR3mS6RkIg7V95ATlnr1g/0VEICgNfvfFegPh5ANPmADHFTt2m
5
+ tc+d1EomsTSw4f5D++Cj70aqIgHdjI9+ljQWetNhAFev53yd8VGeV6gijJDLYJUe
6
+ BfZkTUrmyxu7kHS6RLkc4F1uUkHAc9Lbkp2E/McePvj4Y64n6nbe4PhqygPCuB4G
7
+ ee4s+o38WzLWVEW41d+4GlXxbKQz8ZFETfMqRQIDAQABAoIBABbS8z/alAgPFIu8
8
+ i0ANp2VUhVTe6jD9HQCQFm5xLSWCjHjKQkxWTCF98xglCk1CbVlzq88xPxPNOXGs
9
+ fJ1vAnsudproVJrvTRcXZQob28e3MQ0lBHQI8UWSsu9w5SdDOqxiTf9O8RRAK7sh
10
+ AZqz9Gr403LY2aT+Demk659VikeBMbgxbB+uABTP9SNvngFZcBoOZwwwavPkuYVc
11
+ qei9nhVBfFvZA9iwsUNbTI3kBTfguXgz+gOcB5erNfWRkeOYIEE/V1A8WpnAXU0f
12
+ UQ0tlebztaeM38AiTaRyDdgGVbN0HhTIkc3JI3B3UqV4D3WNlQLowAut88klSX4F
13
+ wkKsSC0CgYEA6hLfYcuMDhZhFtaF4Zhh2lOYazI2oYEEr65uE0dGOmkPTQdnkgoa
14
+ KizWX4reMB5km7OE7qZBBx9uBxMi7kaH5cWdBYtRUL+crqmiiDpMKqlzEFzt0L/o
15
+ XtFEqS+A6w9Sd3QfTlS2qME5+vKSICueLN7UJfY/8SsQDNk1WaCfUYcCgYEA2umr
16
+ bP3sSKGltwwoZ94qu9J4Exq9F+5ROxZ59p3FGarOIOAxHK0HrHXpYi46t1dTS6HH
17
+ CiarbDGjRFaHH2V3ilox5Lcisj480x4hc8TjupF7s+HAXLy+bZK/yFfhJ+cG4hEa
18
+ AHLye0vnRWGL9FkOxudl6D9atDP58Q/SDufjSNMCgYB9syjWobJSll4JH6bB4U0b
19
+ K608U7jWvixAE9H09F+YWnbnDMTnvhkS8QUmRbLP8GJi4uLOLeXZ51z026f0gVfV
20
+ YmvSYGCIln2TpnEr6vKgLmMmNGFZqtUkpgjTOjlnAdFtaKSvMfrtYOa8BqvGLuZA
21
+ fmE7CaSI5HE4FST7PrCP3QKBgQDEsye0dGjGTnD/i+4Wflr5j0ETMXhtM1dL94M5
22
+ ZEQBLyeuBKQ8dwEpJn3BGXbq3I1crQ2SgnKPcf6Y3gLl5B9IcojYUPHdJO00aaN3
23
+ SZeyQRzc4eEdsv6MqEqo8sW+O+lEYkdx1dcpkGdLQT4nHYqYkL1RtPOEbhuMTkHZ
24
+ 4OSpvwKBgQC+bKRln4APRwLlWkxQlLs+2vUte4sFkKDcNIL205V7j6HRHl8t9ux4
25
+ SocyhDmxuBXJTEAqw5eKo7i82gZdox+jjHan/AgtpxKavSX3kchi3R54y4O1/HJy
26
+ t3IowIES6rJCmMf6+qYrxTBxfxM4dKNOZVmbD0faNLt7g/DtlmVnMg==
27
+ -----END RSA PRIVATE KEY-----
@@ -0,0 +1,135 @@
1
+ require 'test_helper'
2
+ describe Qurd::Listener do
3
+ include WebMockStubs
4
+
5
+ let(:queue_url) { 'https://sqs.us-west-2.amazonaws.com/123456890/test2-ScalingNotificationsQueue-HPPYDAYSAGAI1' }
6
+ let(:queue_name) { queue_url[/([^\/]+$)/] }
7
+ let(:subject) do
8
+ Qurd::Listener.new(
9
+ aws_credentials: Aws::Credentials.new('abc', 'def'),
10
+ region: 'us-west-2',
11
+ name: 'staging',
12
+ visibility_timeout: '1',
13
+ wait_time: '0',
14
+ queues: [queue_name]
15
+ )
16
+ end
17
+
18
+ def setup
19
+ aws_sqs_list_queues
20
+ aws_sqs_set_queue_attributes
21
+ aws_sqs_receive_message 'test/responses/aws/sqs-receive-message-1-launch.xml'
22
+ Qurd::Configuration.instance.init('test/inputs/qurd.yml')
23
+ end
24
+
25
+ describe '#listen' do
26
+ it 'is complicated' do
27
+ skip 'hmmm..'
28
+ end
29
+ end
30
+
31
+ describe '#queue_threads' do
32
+ it 'creates one thread per queue' do
33
+ threads = subject.queue_threads do |url, ctx|
34
+ url.must_equal queue_url
35
+ ctx.must_be_kind_of Cabin::Context
36
+ end
37
+ threads.count.must_equal 1
38
+ threads.first.must_be_kind_of Thread
39
+ end
40
+ end
41
+
42
+ describe '#configure_queues' do
43
+ it 'is complicated' do
44
+ skip 'hmmm..'
45
+ end
46
+ end
47
+
48
+ describe '#new' do
49
+ def get_ivar(name)
50
+ subject.instance_variable_get name.to_sym
51
+ end
52
+ let(:attrs) do
53
+ creds = Aws::Credentials.new('abc', 'def')
54
+ {
55
+ aws_credentials: creds,
56
+ name: 'staging',
57
+ queues: [],
58
+ region: 'us-west-2',
59
+ visibility_timeout: '0',
60
+ wait_time: '1'
61
+ }
62
+ end
63
+ let(:subject) { Qurd::Listener.new(attrs) }
64
+ it 'sets ivars' do
65
+ get_ivar(:@aws_credentials).must_be_kind_of Aws::Credentials
66
+ get_ivar(:@name).must_equal 'staging'
67
+ get_ivar(:@visibility_timeout).must_equal '0'
68
+ get_ivar(:@wait_time).must_equal '1'
69
+ get_ivar(:@queues).must_equal []
70
+ end
71
+ end
72
+
73
+ describe '#convert_queues' do
74
+ it "logs if a queue string doesn't match anything" do
75
+ mock = Minitest::Mock.new
76
+ mock.expect :debug, nil, [String]
77
+ mock.expect :warn, nil, ["No queue found for 'FooQueue'"]
78
+ subject.stub :qurd_logger, mock do
79
+ ret = subject.send :convert_queues, ['FooQueue']
80
+ ret.must_be :empty?
81
+ end
82
+ mock.verify
83
+ end
84
+
85
+ it "logs if a queue regex doesn't match anything" do
86
+ mock = Minitest::Mock.new
87
+ mock.expect :debug, nil, [String]
88
+ mock.expect :debug, nil, [String]
89
+ mock.expect :debug, nil, [String]
90
+ mock.expect :warn, nil, ["No queue found for '(?-mix:FooQueue)'"]
91
+ subject.stub :qurd_logger, mock do
92
+ ret = subject.send :convert_queues, ['/FooQueue/']
93
+ ret.must_be :empty?
94
+ end
95
+ mock.verify
96
+ end
97
+
98
+ it 'converts names to urls' do
99
+ ret = subject.send :convert_queues, [queue_name]
100
+ ret.must_equal [queue_url]
101
+ end
102
+
103
+ it 'converts regexes to urls' do
104
+ expected = %w(
105
+ https://sqs.us-west-2.amazonaws.com/123456890/test2-ScalingNotificationsQueue-HPPYDAYSAGAI1
106
+ https://us-west-2.queue.amazonaws.com/123456890/test3-ScalingNotificationsQueue-YYLG1O990SQI
107
+ https://us-west-2.queue.amazonaws.com/123456890/test4-ScalingNotificationsQueue-1S1YEQQE2J7HI
108
+ https://us-west-2.queue.amazonaws.com/123456890/test5-ScalingNotificationsQueue-55KK8HVCUXAL
109
+ https://us-west-2.queue.amazonaws.com/123456890/test6-ScalingNotificationsQueue-HLG212XCGF9J
110
+ https://us-west-2.queue.amazonaws.com/123456890/test7-ScalingNotificationsQueue-WBJFMQLXPJTE
111
+ https://us-west-2.queue.amazonaws.com/123456890/test8-ScalingNotificationsQueue-1D4ZH9NTVP54Y
112
+ https://us-west-2.queue.amazonaws.com/123456890/test9-ScalingNotificationsQueue-1XU3PAR1WTHCU
113
+ https://us-west-2.queue.amazonaws.com/123456890/test10-ScalingNotificationsQueue-1UMGYCSIB1JH8
114
+ https://us-west-2.queue.amazonaws.com/123456890/test11-ScalingNotificationsQueue-L0AKLNJ1XLBS
115
+ https://us-west-2.queue.amazonaws.com/123456890/test12-ScalingNotificationsQueue-M09A379WLWFU
116
+ https://us-west-2.queue.amazonaws.com/123456890/test13-ScalingNotificationsQueue-100VMU8AM3HT3
117
+ https://us-west-2.queue.amazonaws.com/123456890/test14-ScalingNotificationsQueue-EL0IF9EJIIZ2
118
+ https://us-west-2.queue.amazonaws.com/123456890/test15-ScalingNotificationsQueue-U701AIYCF4W4
119
+ https://us-west-2.queue.amazonaws.com/123456890/test15-ScalingNotificationsQueue-1QFI52GEJIW
120
+ https://us-west-2.queue.amazonaws.com/123456890/test16-ScalingNotificationsQueue-1SR2WCCTHI4O
121
+ https://us-west-2.queue.amazonaws.com/123456890/test17-ScalingNotificationsQueue-BQSIQV79C3A1
122
+ https://us-west-2.queue.amazonaws.com/123456890/test18-ScalingNotificationsQueue-1TDIPXAVBWD73
123
+ https://us-west-2.queue.amazonaws.com/123456890/test19-ScalingNotificationsQueue-1U30UKNUS17YY
124
+ )
125
+ ret = subject.send :convert_queues, ['/ScalingNotificationsQueue/']
126
+ ret.must_equal expected
127
+ ret = subject.send :convert_queues, ['/scalingnotificationsqueue/i']
128
+ ret.must_equal expected
129
+ ret = subject.send :convert_queues, ["/
130
+ scalingnotificationsqueue # comment
131
+ /xi"]
132
+ ret.must_equal expected
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,187 @@
1
+ require 'test_helper'
2
+ describe Qurd::Message do
3
+ include WebMockStubs
4
+
5
+ let(:sqs_client) { Aws::SQS::Client.new(region: 'us-west-2') }
6
+ let(:queue_url) { 'https://sqs.us-west-2.amazonaws.com/123456890/test2-ScalingNotificationsQueue-HPPYDAYSAGAI1' }
7
+ let(:sqs_message) { sqs_client.receive_message(queue_url: queue_url).messages.first }
8
+ let(:subject) do
9
+ Qurd::Message.new(
10
+ message: sqs_message,
11
+ aws_credentials: Aws::Credentials.new('abc', 'def'),
12
+ region: 'us-west-2')
13
+ end
14
+
15
+ describe '#add_accessor' do
16
+ it 'adds getter and setter methods' do
17
+ methods = [:test_method, :test_method=]
18
+ methods.each do |method|
19
+ t = Qurd::Message.instance_methods.include?(method)
20
+ t.must_equal false
21
+ end
22
+ Qurd::Message.add_accessor(:test_method)
23
+ methods.each do |method|
24
+ t = Qurd::Message.instance_methods.include?(method)
25
+ t.must_equal true
26
+ end
27
+ end
28
+ end
29
+
30
+ describe 'configuration mixin' do
31
+ it 'responds to #qurd_config' do
32
+ aws_sqs_receive_message 'test/responses/aws/sqs-receive-message-1-launch.xml'
33
+ subject.must_respond_to :qurd_config
34
+ end
35
+ end
36
+
37
+ describe '#new' do
38
+ def setup
39
+ aws_sqs_receive_message 'test/responses/aws/sqs-receive-message-1-launch.xml'
40
+ end
41
+
42
+ def get_ivar(name)
43
+ subject.instance_variable_get name.to_sym
44
+ end
45
+
46
+ it 'sets various ivars' do
47
+ get_ivar(:@aws_credentials).must_be_kind_of Aws::Credentials
48
+ # changes between #receive_message calls
49
+ get_ivar(:@context).must_be_kind_of Cabin::Context
50
+ get_ivar(:@region).must_equal 'us-west-2'
51
+ get_ivar(:@failed).must_equal false
52
+ get_ivar(:@exceptions).must_equal []
53
+ end
54
+ end
55
+
56
+ describe '#body' do
57
+ def setup
58
+ aws_sqs_receive_message 'test/responses/aws/sqs-receive-message-1-launch.xml'
59
+ end
60
+ it 'converts json to a mash' do
61
+ subject.body.must_be_kind_of Hashie::Mash
62
+ end
63
+ end
64
+
65
+ describe '#message' do
66
+ def setup
67
+ aws_sqs_receive_message 'test/responses/aws/sqs-receive-message-1-launch.xml'
68
+ end
69
+ it 'converts json to a mash' do
70
+ subject.message.must_be_kind_of Hashie::Mash
71
+ end
72
+ end
73
+
74
+ describe '#receipt_handle' do
75
+ def setup
76
+ aws_sqs_receive_message 'test/responses/aws/sqs-receive-message-1-launch.xml'
77
+ end
78
+ it 'retrieves the message\'s receipt handle' do
79
+ subject.receipt_handle.must_equal 'foobar=='
80
+ end
81
+ end
82
+
83
+ describe '#message_id' do
84
+ def setup
85
+ aws_sqs_receive_message 'test/responses/aws/sqs-receive-message-1-launch.xml'
86
+ end
87
+ it 'retrieves the message\'s message id' do
88
+ subject.message_id.must_be_kind_of String
89
+ end
90
+ end
91
+
92
+ describe '#failed!' do
93
+ def setup
94
+ aws_sqs_receive_message 'test/responses/aws/sqs-receive-message-1-launch.xml'
95
+ end
96
+
97
+ it 'records an exception' do
98
+ expected = Exception.new('foo')
99
+ subject.failed! expected
100
+ subject.exceptions.must_equal [expected]
101
+ end
102
+
103
+ it 'set failed to true' do
104
+ subject.failed!
105
+ subject.instance_variable_get(:@failed).must_equal true
106
+ end
107
+ end
108
+
109
+ describe '#failed?' do
110
+ def setup
111
+ aws_sqs_receive_message 'test/responses/aws/sqs-receive-message-1-launch.xml'
112
+ end
113
+
114
+ it 'is false' do
115
+ subject.failed?.must_equal false
116
+ end
117
+
118
+ it 'is true' do
119
+ subject.failed!
120
+ subject.failed?.must_equal true
121
+ end
122
+ end
123
+
124
+ describe '#action' do
125
+ %w[launch launch_error terminate terminate_error test].each do |action|
126
+ it "is #{action}" do
127
+ aws_sqs_receive_message "test/responses/aws/sqs-receive-message-1-#{action}.xml"
128
+ subject.action.must_equal action
129
+ end
130
+ end
131
+
132
+ it 'is nil' do
133
+ aws_sqs_receive_message 'test/responses/aws/sqs-receive-message-1-other.xml'
134
+ subject.action.must_equal nil
135
+ end
136
+ end
137
+
138
+ describe '#instance' do
139
+ def setup
140
+ aws_sqs_receive_message 'test/responses/aws/sqs-receive-message-1-launch.xml'
141
+ end
142
+
143
+ it 'returns an instance' do
144
+ aws_ec2_describe_instances 'test/responses/aws/ec2-describe-instances-1.xml'
145
+ subject.instance.must_be_kind_of Struct
146
+ end
147
+
148
+ it 'returns nil' do
149
+ aws_ec2_describe_instances 'test/responses/aws/ec2-describe-instances-0.xml'
150
+ subject.instance.must_equal nil
151
+ end
152
+
153
+ it 'raises Aws::EC2::Errors::InvalidInstanceIDNotFound' do
154
+ aws_ec2_describe_instances 'test/responses/aws/ec2-describe-instances-0.xml', 500
155
+ lambda {
156
+ subject.instance(0)
157
+ }.must_raise Aws::EC2::Errors::InvalidInstanceIDNotFound
158
+ end
159
+ end
160
+
161
+ describe '#instance_name' do
162
+ def setup
163
+ aws_sqs_receive_message 'test/responses/aws/sqs-receive-message-1-launch.xml'
164
+ end
165
+
166
+ it 'returns an instance name' do
167
+ aws_ec2_describe_instances 'test/responses/aws/ec2-describe-instances-1.xml'
168
+ subject.instance_name.must_equal 'test-414.staging.example.com'
169
+ end
170
+
171
+ it 'returns nil' do
172
+ aws_ec2_describe_instances 'test/responses/aws/ec2-describe-instances-0.xml'
173
+ subject.instance_name.must_equal nil
174
+ end
175
+
176
+ end
177
+
178
+ describe '#aws_instance' do
179
+ it 'returns nil, if instance_id is nil' do
180
+ aws_sqs_receive_message 'test/responses/aws/sqs-receive-message-1-launch.xml'
181
+ subject.stub :instance_id, nil do
182
+ subject.send(:aws_instance).must_equal nil
183
+ end
184
+ end
185
+ end
186
+
187
+ end