elasticity 5.0.3 → 6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/HISTORY.md +26 -0
  3. data/README.md +35 -28
  4. data/elasticity.gemspec +2 -2
  5. data/lib/elasticity.rb +5 -3
  6. data/lib/elasticity/aws_request_v4.rb +15 -3
  7. data/lib/elasticity/aws_session.rb +4 -23
  8. data/lib/elasticity/aws_utils.rb +0 -29
  9. data/lib/elasticity/cluster_status.rb +38 -0
  10. data/lib/elasticity/cluster_step_status.rb +51 -0
  11. data/lib/elasticity/emr.rb +208 -78
  12. data/lib/elasticity/job_flow.rb +16 -17
  13. data/lib/elasticity/version.rb +1 -1
  14. data/spec/factories/cluster_status_factory.rb +12 -0
  15. data/spec/factories/cluster_step_status_factory.rb +17 -0
  16. data/spec/lib/elasticity/aws_request_v4_spec.rb +54 -4
  17. data/spec/lib/elasticity/aws_session_spec.rb +22 -88
  18. data/spec/lib/elasticity/aws_utils_spec.rb +0 -46
  19. data/spec/lib/elasticity/bootstrap_action_spec.rb +7 -3
  20. data/spec/lib/elasticity/cluster_status_spec.rb +98 -0
  21. data/spec/lib/elasticity/cluster_step_status_spec.rb +80 -0
  22. data/spec/lib/elasticity/custom_jar_step_spec.rb +10 -7
  23. data/spec/lib/elasticity/emr_spec.rb +422 -132
  24. data/spec/lib/elasticity/ganglia_bootstrap_action_spec.rb +8 -3
  25. data/spec/lib/elasticity/hadoop_bootstrap_action_spec.rb +8 -3
  26. data/spec/lib/elasticity/hadoop_file_bootstrap_action_spec.rb +7 -3
  27. data/spec/lib/elasticity/hive_step_spec.rb +21 -17
  28. data/spec/lib/elasticity/instance_group_spec.rb +9 -5
  29. data/spec/lib/elasticity/job_flow_integration_spec.rb +4 -4
  30. data/spec/lib/elasticity/job_flow_spec.rb +102 -76
  31. data/spec/lib/elasticity/job_flow_step_spec.rb +1 -1
  32. data/spec/lib/elasticity/looper_spec.rb +1 -1
  33. data/spec/lib/elasticity/pig_step_spec.rb +13 -9
  34. data/spec/lib/elasticity/s3distcp_step_spec.rb +7 -5
  35. data/spec/lib/elasticity/script_step_spec.rb +11 -6
  36. data/spec/lib/elasticity/setup_hadoop_debugging_step_spec.rb +9 -5
  37. data/spec/lib/elasticity/streaming_step_spec.rb +13 -9
  38. data/spec/spec_helper.rb +8 -0
  39. data/spec/support/factory_girl.rb +8 -0
  40. metadata +24 -21
  41. data/lib/elasticity/aws_request_v2.rb +0 -42
  42. data/lib/elasticity/job_flow_status.rb +0 -91
  43. data/lib/elasticity/job_flow_status_step.rb +0 -38
  44. data/spec/lib/elasticity/aws_request_v2_spec.rb +0 -38
  45. data/spec/lib/elasticity/job_flow_status_spec.rb +0 -265
  46. data/spec/lib/elasticity/job_flow_status_step_spec.rb +0 -80
@@ -1,23 +1,20 @@
1
1
  describe Elasticity::EMR do
2
2
 
3
3
  subject do
4
- Elasticity::EMR.new('ACCESS', 'SECRET')
4
+ Elasticity::EMR.new(:region => 'TEST_REGION')
5
5
  end
6
6
 
7
- describe '.new' do
7
+ describe '.initialize' do
8
8
 
9
9
  context 'when arguments are provided' do
10
- its(:aws_request) { should == Elasticity::AwsSession.new('ACCESS', 'SECRET', {}) }
10
+ it 'should use the provided arguments' do
11
+ expect(subject.aws_request).to eq(Elasticity::AwsSession.new(:region => 'TEST_REGION'))
12
+ end
11
13
  end
12
-
13
14
  context 'when arguments are not provided' do
14
- before do
15
- ENV.stub(:[]).with('AWS_ACCESS_KEY_ID').and_return('ENV_ACCESS')
16
- ENV.stub(:[]).with('AWS_SECRET_ACCESS_KEY').and_return('ENV_SECRET')
17
- end
18
15
  it 'should use environment variables' do
19
16
  emr = Elasticity::EMR.new
20
- emr.aws_request.should == Elasticity::AwsSession.new('ENV_ACCESS', 'ENV_SECRET', {})
17
+ emr.aws_request.should == Elasticity::AwsSession.new({})
21
18
  end
22
19
  end
23
20
 
@@ -25,31 +22,25 @@ describe Elasticity::EMR do
25
22
 
26
23
  describe '#add_instance_groups' do
27
24
 
25
+ let(:aws_response) do
26
+ <<-JSON
27
+ {
28
+ "InstanceGroupIds": ["ig-1", "ig-2", "ig-3"],
29
+ "JobFlowId": "j-3U7TSX5GZFD8Y"
30
+ }
31
+ JSON
32
+ end
33
+
28
34
  it 'should send the correct params to AWS' do
29
35
  Elasticity::AwsSession.any_instance.should_receive(:submit).with({
30
36
  :operation => 'AddInstanceGroups',
31
37
  :job_flow_id => 'JOBFLOW_ID',
32
38
  :instance_groups => ['INSTANCE_GROUP_CONFIGS']
33
- })
39
+ }).and_return(aws_response)
34
40
  subject.add_instance_groups('JOBFLOW_ID', ['INSTANCE_GROUP_CONFIGS'])
35
41
  end
36
42
 
37
43
  describe 'return values' do
38
- let(:aws_response) do
39
- <<-XML
40
- <AddInstanceGroupsResponse xmlns="http://elasticmapreduce.amazonaws.com/doc/2009-03-31">
41
- <AddInstanceGroupsResult>
42
- <JobFlowId>j-OALI7TZTQMHX</JobFlowId>
43
- <InstanceGroupIds>
44
- <member>ig-1</member>
45
- <member>ig-2</member>
46
- <member>ig-3</member>
47
- </InstanceGroupIds>
48
- </AddInstanceGroupsResult>
49
- </AddInstanceGroupsResponse>
50
- XML
51
- end
52
-
53
44
  it 'should return an array of the new instance groups IDs' do
54
45
  Elasticity::AwsSession.any_instance.should_receive(:submit).and_return(aws_response)
55
46
  subject.add_instance_groups('', []).should == ['ig-1', 'ig-2', 'ig-3']
@@ -57,11 +48,10 @@ describe Elasticity::EMR do
57
48
  end
58
49
 
59
50
  context 'when a block is given' do
60
- let(:result) { 'RESULT' }
61
51
  it 'should yield the submission results' do
62
- Elasticity::AwsSession.any_instance.should_receive(:submit).and_return(result)
63
- subject.add_instance_groups('', []) do |xml|
64
- xml.should == 'RESULT'
52
+ Elasticity::AwsSession.any_instance.should_receive(:submit).and_return(aws_response)
53
+ subject.add_instance_groups('', []) do |result|
54
+ result.should == aws_response
65
55
  end
66
56
  end
67
57
  end
@@ -70,147 +60,367 @@ describe Elasticity::EMR do
70
60
 
71
61
  describe '#add_jobflow_steps' do
72
62
 
63
+ let(:aws_result) {
64
+ <<-JSON
65
+ {"Key" : "Value"}
66
+ JSON
67
+ }
68
+
73
69
  it 'should add the specified steps to the job flow' do
74
70
  Elasticity::AwsSession.any_instance.should_receive(:submit).with({
75
71
  :operation => 'AddJobFlowSteps',
76
72
  :job_flow_id => 'JOBFLOW_ID',
77
73
  :steps => ['_']
78
- })
79
- subject.add_jobflow_steps('JOBFLOW_ID', {:steps => ['_']})
74
+ }).and_return(aws_result)
75
+ expect(subject.add_jobflow_steps('JOBFLOW_ID', ['_'])).to eql(JSON.parse(aws_result))
80
76
  end
81
77
 
82
78
  context 'when a block is given' do
83
- let(:result) { 'RESULT' }
84
79
  it 'should yield the submission results' do
85
- Elasticity::AwsSession.any_instance.should_receive(:submit).and_return(result)
86
- subject.add_jobflow_steps('', {}) do |xml|
87
- xml.should == 'RESULT'
80
+ Elasticity::AwsSession.any_instance.should_receive(:submit).and_return(aws_result)
81
+ subject.add_jobflow_steps('', []) do |result|
82
+ result.should == aws_result
88
83
  end
89
84
  end
90
85
  end
91
86
 
92
87
  end
93
88
 
94
- describe '#describe_jobflows' do
95
-
96
- let(:describe_jobflows_xml) do
97
- <<-XML
98
- <DescribeJobFlowsResponse xmlns="http://elasticmapreduce.amazonaws.com/doc/2009-03-31">
99
- <DescribeJobFlowsResult>
100
- <JobFlows>
101
- <member>
102
- <ExecutionStatusDetail>
103
- <CreationDateTime>2011-04-04T17:41:51Z</CreationDateTime>
104
- <State>TERMINATED</State>
105
- </ExecutionStatusDetail>
106
- <JobFlowId>j-p</JobFlowId>
107
- <Name>Pig Job</Name>
108
- </member>
109
- <member>
110
- <ExecutionStatusDetail>
111
- <State>TERMINATED</State>
112
- <CreationDateTime>2011-04-04T17:41:51Z</CreationDateTime>
113
- </ExecutionStatusDetail>
114
- <JobFlowId>j-h</JobFlowId>
115
- <Name>Hive Job</Name>
116
- </member>
117
- </JobFlows>
118
- </DescribeJobFlowsResult>
119
- </DescribeJobFlowsResponse>
120
- XML
121
- end
122
-
123
- it 'should return an array of properly populated JobFlowStatusES' do
124
- Elasticity::AwsSession.any_instance.should_receive(:submit).and_return(describe_jobflows_xml)
125
- jobflow_statuses = subject.describe_jobflows
126
- jobflow_statuses.map(&:name).should == ['Pig Job', 'Hive Job']
127
- jobflow_statuses.map(&:class).should == [Elasticity::JobFlowStatus, Elasticity::JobFlowStatus]
128
- end
129
-
130
- it 'should describe all jobflows' do
89
+ describe '#add_tags' do
90
+
91
+ it 'should modify the jobflow tags' do
131
92
  Elasticity::AwsSession.any_instance.should_receive(:submit).with({
132
- :operation => 'DescribeJobFlows'
133
- })
134
- subject.describe_jobflows
93
+ :operation => 'AddTags',
94
+ :resource_id => 'JOBFLOW_ID',
95
+ :tags => [
96
+ {
97
+ :key => 'TEST_KEY',
98
+ :value => 'TEST_VALUE'
99
+ },
100
+ {
101
+ :key => 'TEST_KEY_ONLY'
102
+ }
103
+ ]
104
+ })
105
+ subject.add_tags('JOBFLOW_ID', [{:key => 'TEST_KEY', :value => 'TEST_VALUE'}, {:key => 'TEST_KEY_ONLY'}])
135
106
  end
136
107
 
137
- context 'when additional parameters are provided' do
138
- it 'should pass them through' do
139
- Elasticity::AwsSession.any_instance.should_receive(:submit).with({
140
- :CreatedBefore => '2011-10-04',
141
- :operation => 'DescribeJobFlows'
142
- })
143
- subject.describe_jobflows(:CreatedBefore => '2011-10-04')
108
+ context 'when a block is given' do
109
+ it 'should yield the submission results' do
110
+ Elasticity::AwsSession.any_instance.should_receive(:submit).and_return('RESULT')
111
+ subject.add_tags('', {}) do |result|
112
+ result.should == 'RESULT'
113
+ end
144
114
  end
145
115
  end
146
116
 
117
+ end
118
+
119
+ describe '#describe_cluster' do
120
+
121
+ let(:aws_result) {
122
+ <<-JSON
123
+ {"Key" : "Value"}
124
+ JSON
125
+ }
126
+
127
+ it 'should describe the specified jobflow' do
128
+ Elasticity::AwsSession.any_instance.should_receive(:submit).with({
129
+ :operation => 'DescribeCluster',
130
+ :cluster_id => 'CLUSTER_ID'
131
+ }).and_return(aws_result)
132
+ expect(subject.describe_cluster('CLUSTER_ID')).to eql(JSON.parse(aws_result))
133
+ end
134
+
147
135
  context 'when a block is given' do
148
- let(:result) { 'RESULT' }
149
136
  it 'should yield the submission results' do
150
- Elasticity::AwsSession.any_instance.should_receive(:submit).and_return(result)
151
- subject.describe_jobflows do |xml|
152
- xml.should == 'RESULT'
137
+ Elasticity::AwsSession.any_instance.should_receive(:submit).and_return(aws_result)
138
+ subject.describe_cluster({}) do |result|
139
+ result.should == aws_result
153
140
  end
154
141
  end
155
142
  end
156
143
 
157
144
  end
158
145
 
159
- describe '#describe_jobflow' do
160
-
161
- let(:describe_jobflows_xml) {
162
- <<-XML
163
- <DescribeJobFlowsResponse xmlns="http://elasticmapreduce.amazonaws.com/doc/2009-03-31">
164
- <DescribeJobFlowsResult>
165
- <JobFlows>
166
- <member>
167
- <JobFlowId>j-3UN6WX5RRO2AG</JobFlowId>
168
- <Name>The One Job Flow</Name>
169
- <ExecutionStatusDetail>
170
- <State>TERMINATED</State>
171
- <CreationDateTime>2011-04-04T17:41:51Z</CreationDateTime>
172
- </ExecutionStatusDetail>
173
- </member>
174
- </JobFlows>
175
- </DescribeJobFlowsResult>
176
- </DescribeJobFlowsResponse>
177
- XML
146
+ describe '#describe_step' do
147
+
148
+ let(:aws_result) {
149
+ <<-JSON
150
+ {"Key" : "Value"}
151
+ JSON
178
152
  }
179
153
 
180
- it 'should describe the specified jobflow' do
154
+ it 'should describe the specified step within the specified jobflow' do
181
155
  Elasticity::AwsSession.any_instance.should_receive(:submit).with({
182
- :operation => 'DescribeJobFlows',
183
- :job_flow_ids => ['j-3UN6WX5RRO2AG']
184
- })
185
- subject.describe_jobflow('j-3UN6WX5RRO2AG')
156
+ :operation => 'DescribeStep',
157
+ :cluster_id => 'CLUSTER_ID',
158
+ :step_id => 'STEP_ID'
159
+ }).and_return(aws_result)
160
+ expect(subject.describe_step('CLUSTER_ID', 'STEP_ID')).to eql(JSON.parse(aws_result))
161
+ end
162
+
163
+ context 'when a block is given' do
164
+ it 'should yield the submission results' do
165
+ Elasticity::AwsSession.any_instance.should_receive(:submit).and_return(aws_result)
166
+ subject.describe_step('', '') do |result|
167
+ result.should == aws_result
168
+ end
169
+ end
170
+ end
171
+
172
+ end
173
+
174
+ describe '#list_instance_groups' do
175
+
176
+ let(:aws_result) {
177
+ <<-JSON
178
+ {"Key" : "Value"}
179
+ JSON
180
+ }
181
+
182
+ it 'should list the instance groups in the specified jobflow' do
183
+ Elasticity::AwsSession.any_instance.should_receive(:submit).with({
184
+ :operation => 'ListInstanceGroups',
185
+ :cluster_id => 'CLUSTER_ID'
186
+ }).and_return(aws_result)
187
+ expect(subject.list_instance_groups('CLUSTER_ID')).to eql(JSON.parse(aws_result))
188
+ end
189
+
190
+ context 'when a block is given' do
191
+ it 'should yield the submission results' do
192
+ Elasticity::AwsSession.any_instance.should_receive(:submit).and_return(aws_result)
193
+ subject.list_instance_groups({}) do |result|
194
+ result.should == aws_result
195
+ end
196
+ end
186
197
  end
187
198
 
188
- it 'should return a properly populated JobFlowStatus' do
189
- Elasticity::AwsSession.any_instance.should_receive(:submit).and_return(describe_jobflows_xml)
190
- jobflow_status = subject.describe_jobflow('_')
191
- jobflow_status.should be_a Elasticity::JobFlowStatus
192
- jobflow_status.jobflow_id.should == 'j-3UN6WX5RRO2AG'
199
+ end
200
+
201
+ describe '#list_bootstrap_actions' do
202
+
203
+ let(:aws_result) {
204
+ <<-JSON
205
+ {"Key" : "Value"}
206
+ JSON
207
+ }
208
+
209
+ it 'should list the bootstrap actions in the specified jobflow' do
210
+ Elasticity::AwsSession.any_instance.should_receive(:submit).with({
211
+ :operation => 'ListBootstrapActions',
212
+ :cluster_id => 'CLUSTER_ID'
213
+ }).and_return(aws_result)
214
+ expect(subject.list_bootstrap_actions('CLUSTER_ID')).to eql(JSON.parse(aws_result))
193
215
  end
194
216
 
195
217
  context 'when a block is given' do
196
- let(:result) { 'RESULT' }
197
218
  it 'should yield the submission results' do
198
- Elasticity::AwsSession.any_instance.should_receive(:submit).and_return(result)
199
- subject.describe_jobflow('') do |xml|
200
- xml.should == 'RESULT'
219
+ Elasticity::AwsSession.any_instance.should_receive(:submit).and_return(aws_result)
220
+ subject.list_bootstrap_actions({}) do |result|
221
+ result.should == aws_result
201
222
  end
202
223
  end
203
224
  end
225
+
204
226
  end
205
227
 
206
- describe '#describe_jobflow_xml' do
228
+ describe '#list_clusters' do
207
229
 
208
230
  before do
209
- subject.should_receive(:describe_jobflow).with('JOBFLOW_ID').and_yield('XML_RESULT')
231
+ Timecop.freeze(Time.at(1302461096))
232
+ end
233
+
234
+ after do
235
+ Timecop.return
236
+ end
237
+
238
+ let(:aws_result) {
239
+ <<-JSON
240
+ {"Key" : "Value"}
241
+ JSON
242
+ }
243
+
244
+ context 'when no arguments are supplied' do
245
+ it 'should list all clusters' do
246
+ Elasticity::AwsSession.any_instance.should_receive(:submit).with({
247
+ :operation => 'ListClusters'
248
+ }).and_return(aws_result)
249
+ expect(subject.list_clusters).to eql(JSON.parse(aws_result))
250
+ end
251
+ end
252
+
253
+ context 'when statuses are given' do
254
+ it 'should list clusters with the specified status' do
255
+ Elasticity::AwsSession.any_instance.should_receive(:submit).with({
256
+ :operation => 'ListClusters',
257
+ :cluster_states => ['STATE1', 'STATE2']
258
+ }).and_return(aws_result)
259
+ expect(subject.list_clusters({:states => ['STATE1', 'STATE2']})).to eql(JSON.parse(aws_result))
260
+ end
261
+ end
262
+
263
+ context 'when a before date is given' do
264
+ it 'should list clusters created before that date' do
265
+ Elasticity::AwsSession.any_instance.should_receive(:submit).with({
266
+ :operation => 'ListClusters',
267
+ :created_before => 1302461096
268
+ }).and_return(aws_result)
269
+ expect(subject.list_clusters({:created_before => Time.now})).to eql(JSON.parse(aws_result))
270
+ end
271
+ end
272
+
273
+ context 'when an after date is given' do
274
+ it 'should list clusters created after that date' do
275
+ Elasticity::AwsSession.any_instance.should_receive(:submit).with({
276
+ :operation => 'ListClusters',
277
+ :created_after => 1302461096
278
+ }).and_return(aws_result)
279
+ expect(subject.list_clusters({:created_after => Time.now})).to eql(JSON.parse(aws_result))
280
+ end
281
+ end
282
+
283
+ context 'when a pagination token is specified' do
284
+ it 'should supply the appropriate page' do
285
+ Elasticity::AwsSession.any_instance.should_receive(:submit).with({
286
+ :operation => 'ListClusters',
287
+ :marker => 'MARKER'
288
+ }).and_return(aws_result)
289
+ expect(subject.list_clusters({:marker => 'MARKER'})).to eql(JSON.parse(aws_result))
290
+ end
291
+ end
292
+
293
+ context 'when a block is given' do
294
+ it 'should yield the submission results' do
295
+ Elasticity::AwsSession.any_instance.should_receive(:submit).and_return(aws_result)
296
+ subject.list_bootstrap_actions({}) do |result|
297
+ result.should == aws_result
298
+ end
299
+ end
300
+ end
301
+
302
+ end
303
+
304
+ describe '#list_instances' do
305
+
306
+ let(:aws_result) {
307
+ <<-JSON
308
+ {"Key" : "Value"}
309
+ JSON
310
+ }
311
+
312
+ context 'when no arguments are supplied' do
313
+ it 'should list all instances in the cluster' do
314
+ Elasticity::AwsSession.any_instance.should_receive(:submit).with({
315
+ :operation => 'ListInstances',
316
+ :cluster_id => 'CLUSTER_ID'
317
+ }).and_return(aws_result)
318
+ expect(subject.list_instances('CLUSTER_ID')).to eql(JSON.parse(aws_result))
319
+ end
320
+ end
321
+
322
+ context 'when an instance group is specified' do
323
+ it 'should list the instances in that group' do
324
+ Elasticity::AwsSession.any_instance.should_receive(:submit).with({
325
+ :operation => 'ListInstances',
326
+ :cluster_id => 'CLUSTER_ID',
327
+ :instance_group_id => 'INSTANCE_GROUP_ID'
328
+ }).and_return(aws_result)
329
+ expect(subject.list_instances('CLUSTER_ID', {:instance_group_id => 'INSTANCE_GROUP_ID'})).to eql(JSON.parse(aws_result))
330
+ end
331
+ end
332
+
333
+ context 'when instance types are specified' do
334
+ it 'should list the instances of that type' do
335
+ Elasticity::AwsSession.any_instance.should_receive(:submit).with({
336
+ :operation => 'ListInstances',
337
+ :cluster_id => 'CLUSTER_ID',
338
+ :instance_group_types => ['TYPE1', 'TYPE2']
339
+ }).and_return(aws_result)
340
+ expect(subject.list_instances('CLUSTER_ID', {:instance_group_types => ['TYPE1', 'TYPE2']})).to eql(JSON.parse(aws_result))
341
+ end
342
+ end
343
+
344
+ context 'when a pagination token is specified' do
345
+ it 'should supply the appropriate page' do
346
+ Elasticity::AwsSession.any_instance.should_receive(:submit).with({
347
+ :operation => 'ListInstances',
348
+ :cluster_id => 'CLUSTER_ID',
349
+ :marker => 'MARKER'
350
+ }).and_return(aws_result)
351
+ expect(subject.list_instances('CLUSTER_ID', {:marker => 'MARKER'})).to eql(JSON.parse(aws_result))
352
+ end
353
+ end
354
+
355
+ context 'when a block is given' do
356
+ it 'should yield the submission results' do
357
+ Elasticity::AwsSession.any_instance.should_receive(:submit).and_return(aws_result)
358
+ subject.list_instances({}) do |result|
359
+ result.should == aws_result
360
+ end
361
+ end
362
+ end
363
+
364
+ end
365
+
366
+ describe '#list_steps' do
367
+
368
+ let(:aws_result) {
369
+ <<-JSON
370
+ {"Key" : "Value"}
371
+ JSON
372
+ }
373
+
374
+ context 'when no arguments are supplied' do
375
+ it 'should list all steps in the cluster' do
376
+ Elasticity::AwsSession.any_instance.should_receive(:submit).with({
377
+ :operation => 'ListSteps',
378
+ :cluster_id => 'CLUSTER_ID'
379
+ }).and_return(aws_result)
380
+ expect(subject.list_steps('CLUSTER_ID')).to eql(JSON.parse(aws_result))
381
+ end
382
+ end
383
+
384
+ context 'when step IDs are specified' do
385
+ it 'should list the instances in that group' do
386
+ Elasticity::AwsSession.any_instance.should_receive(:submit).with({
387
+ :operation => 'ListSteps',
388
+ :cluster_id => 'CLUSTER_ID',
389
+ :step_ids => ['S-1', 'S-2']
390
+ }).and_return(aws_result)
391
+ expect(subject.list_steps('CLUSTER_ID', {:step_ids => ['S-1', 'S-2']})).to eql(JSON.parse(aws_result))
392
+ end
393
+ end
394
+
395
+ context 'when step states are specified' do
396
+ it 'should list the steps in that state' do
397
+ Elasticity::AwsSession.any_instance.should_receive(:submit).with({
398
+ :operation => 'ListSteps',
399
+ :cluster_id => 'CLUSTER_ID',
400
+ :step_states => ['STATE1', 'STATE2']
401
+ }).and_return(aws_result)
402
+ expect(subject.list_steps('CLUSTER_ID', {:step_states => ['STATE1', 'STATE2']})).to eql(JSON.parse(aws_result))
403
+ end
404
+ end
405
+
406
+ context 'when a pagination token is specified' do
407
+ it 'should supply the appropriate page' do
408
+ Elasticity::AwsSession.any_instance.should_receive(:submit).with({
409
+ :operation => 'ListSteps',
410
+ :cluster_id => 'CLUSTER_ID',
411
+ :marker => 'MARKER'
412
+ }).and_return(aws_result)
413
+ expect(subject.list_steps('CLUSTER_ID', {:marker => 'MARKER'})).to eql(JSON.parse(aws_result))
414
+ end
210
415
  end
211
416
 
212
- it 'should describe the specified jobflow via raw xml text' do
213
- subject.describe_jobflow_xml('JOBFLOW_ID').should == 'XML_RESULT'
417
+ context 'when a block is given' do
418
+ it 'should yield the submission results' do
419
+ Elasticity::AwsSession.any_instance.should_receive(:submit).and_return(aws_result)
420
+ subject.list_steps({}) do |result|
421
+ result.should == aws_result
422
+ end
423
+ end
214
424
  end
215
425
 
216
426
  end
@@ -276,12 +486,24 @@ describe Elasticity::EMR do
276
486
 
277
487
  describe '#terminate_jobflows' do
278
488
 
279
- it 'should terminate the specific jobflow' do
280
- Elasticity::AwsSession.any_instance.should_receive(:submit).with({
281
- :operation => 'TerminateJobFlows',
282
- :job_flow_ids => ['j-1']
283
- })
284
- subject.terminate_jobflows('j-1')
489
+ context 'when one jobflow is specified' do
490
+ it 'should terminate the jobflow' do
491
+ Elasticity::AwsSession.any_instance.should_receive(:submit).with({
492
+ :operation => 'TerminateJobFlows',
493
+ :job_flow_ids => ['j-1']
494
+ })
495
+ subject.terminate_jobflows(['j-1'])
496
+ end
497
+ end
498
+
499
+ context 'when more then one jobflow is specified' do
500
+ it 'should terminate all of the jobflows' do
501
+ Elasticity::AwsSession.any_instance.should_receive(:submit).with({
502
+ :operation => 'TerminateJobFlows',
503
+ :job_flow_ids => ['j-1', 'j-2']
504
+ })
505
+ subject.terminate_jobflows(['j-1', 'j-2'])
506
+ end
285
507
  end
286
508
 
287
509
  context 'when a block is given' do
@@ -296,6 +518,28 @@ describe Elasticity::EMR do
296
518
 
297
519
  end
298
520
 
521
+ describe '#remove_tags' do
522
+
523
+ it 'should remove the jobflow tags' do
524
+ Elasticity::AwsSession.any_instance.should_receive(:submit).with({
525
+ :operation => 'RemoveTags',
526
+ :resource_id => 'JOBFLOW_ID',
527
+ :tag_keys => ['TEST_KEY', 'TEST_KEY_ONLY']
528
+ })
529
+ subject.remove_tags('JOBFLOW_ID', ['TEST_KEY', 'TEST_KEY_ONLY'])
530
+ end
531
+
532
+ context 'when a block is given' do
533
+ it 'should yield the submission results' do
534
+ Elasticity::AwsSession.any_instance.should_receive(:submit).and_return('RESULT')
535
+ subject.remove_tags('', {}) do |result|
536
+ result.should == 'RESULT'
537
+ end
538
+ end
539
+ end
540
+
541
+ end
542
+
299
543
  describe '#set_termination_protection' do
300
544
 
301
545
  context 'when protection is enabled' do
@@ -343,6 +587,53 @@ describe Elasticity::EMR do
343
587
 
344
588
  end
345
589
 
590
+ describe '#set_visible_to_all_users' do
591
+
592
+ context 'when visibility is enabled' do
593
+ it 'should enable visibility on the specified jobflows' do
594
+ Elasticity::AwsSession.any_instance.should_receive(:submit).with({
595
+ :operation => 'SetVisibleToAllUsers',
596
+ :visible_to_all_users => true,
597
+ :job_flow_ids => ['jobflow1', 'jobflow2']
598
+ })
599
+ subject.set_visible_to_all_users(['jobflow1', 'jobflow2'], true)
600
+ end
601
+ end
602
+
603
+ context 'when visibility is disabled' do
604
+ it 'should disable protection on the specified jobflows' do
605
+ Elasticity::AwsSession.any_instance.should_receive(:submit).with({
606
+ :operation => 'SetVisibleToAllUsers',
607
+ :visible_to_all_users => false,
608
+ :job_flow_ids => ['jobflow1', 'jobflow2']
609
+ })
610
+ subject.set_visible_to_all_users(['jobflow1', 'jobflow2'], false)
611
+ end
612
+ end
613
+
614
+ context 'when visibility is not specified' do
615
+ it 'should enable protection on the specified jobflows' do
616
+ Elasticity::AwsSession.any_instance.should_receive(:submit).with({
617
+ :operation => 'SetVisibleToAllUsers',
618
+ :visible_to_all_users => true,
619
+ :job_flow_ids => ['jobflow1', 'jobflow2']
620
+ })
621
+ subject.set_visible_to_all_users(['jobflow1', 'jobflow2'])
622
+ end
623
+ end
624
+
625
+ context 'when a block is given' do
626
+ let(:aws_response) { '_' }
627
+ it 'should yield the termination results' do
628
+ Elasticity::AwsSession.any_instance.should_receive(:submit).and_return(aws_response)
629
+ subject.set_visible_to_all_users([]) do |result|
630
+ result.should == '_'
631
+ end
632
+ end
633
+ end
634
+
635
+ end
636
+
346
637
  describe '#direct' do
347
638
  let(:params) { {:foo => 'bar'} }
348
639
 
@@ -353,11 +644,10 @@ describe Elasticity::EMR do
353
644
  end
354
645
 
355
646
  describe '#==' do
356
- let(:emr1) { Elasticity::EMR.new('ACCESS1', 'SECRET1') }
357
- let(:emr2) { Elasticity::EMR.new('ACCESS2', 'SECRET2') }
647
+ let(:emr1) { Elasticity::EMR.new(:region => 'TEST_REGION1') }
358
648
 
359
649
  let(:same_object) { emr1 }
360
- let(:same_values) { Elasticity::EMR.new('ACCESS1', 'SECRET1') }
650
+ let(:same_values) { Elasticity::EMR.new(:region => 'TEST_REGION1') }
361
651
  let(:diff_type) { Object.new }
362
652
 
363
653
  it 'should pass comparison checks' do