elasticity 0.4 → 0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,18 +1,55 @@
1
- Elasticity provides programmatic access to Amazon's Elastic Map Reduce service.
1
+ Elasticity provides programmatic access to Amazon's Elastic Map Reduce service. The aim is to conveniently wrap the API operations in a manner that makes working with EMR job flows from Ruby more enjoyable. At the very least, using Elasticity allows you to easily experiment with the EMR API :)
2
2
 
3
- There are five API actions in the [http://docs.amazonwebservices.com/ElasticMapReduce/latest/DeveloperGuide/index.html EMR API], described below. Please see the Amazon guide for details on these operations because the default values aren't obvious (e.g. the meaning of <code>DescribeJobFlows</code> without parameters).
3
+ '''BACKLOG''': Have a look at the backlog [https://www.pivotaltracker.com/projects/272429 here] (Pivotal Tracker).
4
+
5
+ '''CREDITS''': AWS signing was used from [http://www.rightscale.com/ RightScale's] amazing [https://github.com/rightscale/right_aws right_aws gem] which works extraordinarily well! If you need access to any AWS service (EC2, S3, etc.), have a look.
6
+
7
+ = Installation and Usage =
8
+
9
+ <pre>
10
+ gem install elasticity
11
+ </pre>
12
+
13
+ All you have to do is <code>require 'elasticity'</code> and you're all set!
4
14
 
5
- Each Elasticity call provides some level of wrapping to save you the trouble of having to parse XML and deal with common status codes.
15
+ = API Reference =
16
+
17
+ Elasticity wraps (well, eventually!) all of the EMR API calls. Please see the Amazon guide for details on these operations because the default values aren't obvious (e.g. the meaning of <code>DescribeJobFlows</code> without parameters).
6
18
 
7
19
  Alternatively, you may opt for "direct" access to the API where you specify the params and Elasticity takes care of the signing for you, responding with the XML from Amazon. Direct access is described below the API catalog.
8
20
 
9
- '''BACKLOG''': Have a look at the backlog [https://www.pivotaltracker.com/projects/272429 here] (Pivotal Tracker).
21
+ In addition to the [http://aws.amazon.com/elasticmapreduce/ AWS EMR subsite], there are three primary resources of reference information for EMR:
10
22
 
11
- '''CREDITS''': AWS signing was used from [http://www.rightscale.com/ RightScale's] amazing [https://github.com/rightscale/right_aws right_aws gem] which works extraordinarily well! If you need access to any AWS service (EC2, S3, etc.), have a look.
23
+ * [http://docs.amazonwebservices.com/ElasticMapReduce/latest/GettingStartedGuide/ Amazon EMR Getting Started Guide]
24
+ * [http://docs.amazonwebservices.com/ElasticMapReduce/latest/DeveloperGuide/ Amazon EMR Developer Guide]
25
+ * [http://docs.amazonwebservices.com/ElasticMapReduce/latest/API/ Amazon EMR API Reference]
26
+
27
+ Unfortunately, the documentation is sometimes incorrect and sometimes missing. E.g. the allowable values for AddInstanceGroups are present in the [http://awsdocs.s3.amazonaws.com/ElasticMapReduce/20090331/emr-api-20090331.pdf PDF] version of the API reference but not in the [http://docs.amazonwebservices.com/ElasticMapReduce/latest/API/ HTML] version. Elasticity implements the API as specified in the PDF reference as that is the most complete description I could find.
12
28
 
13
29
  == AddInstanceGroups ==
14
30
 
15
- ''(not yet supported)''
31
+ AddInstanceGroups adds a group of instances to an existing job flow. The available instance configuration options are listed in the EMR API reference. They've been converted to be more Ruby-like in the wrappers, as shown in the example below.
32
+
33
+ <pre>
34
+ instance_group_config = {
35
+ :count => 1,
36
+ :role => "TASK",
37
+ :type => "m1.small",
38
+ :market => "ON_DEMAND",
39
+ :name => "Go Canucks!"
40
+ }
41
+ emr.add_instance_groups("j-26LIXPUNSC0M3", [instance_group_config])
42
+
43
+ > ["ig-E7C8MGA2ULQ1"]
44
+ </pre>
45
+
46
+ Some combinations of the options will be rejected by Amazon and some once-valid options will sometimes be rejected if they not relevant to the current state of the job flow (e.g. duplicate addition of TASK groups to the same job flow).
47
+
48
+ <pre>
49
+ emr.add_instance_groups("j-26LIXPUNSC0M3", [instance_group_config])
50
+
51
+ > Task instance group already exists in the job flow, cannot add more task groups
52
+ </pre>
16
53
 
17
54
  == AddJobFlowSteps ==
18
55
 
@@ -23,10 +60,11 @@ Alternatively, you may opt for "direct" access to the API where you specify the
23
60
  DescribeJobFlows returns detailed information as to the state of all jobs. Currently this is wrapped in an <code>Elasticity::JobFlow</code> that contains the <code>name</code>, <code>jobflow_id</code> and <code>state</code>.
24
61
 
25
62
  <pre>
26
- > emr = Elasticity::EMR.new(ENV["aws_access_key_id"], ENV["aws_secret_key"])
27
- > jobflows = emr.describe_jobflows
28
- > p jobflows.map(&:name)
29
- ["Hive Test", "Pig Test", "Interactive Hadoop", "Interactive Hive"]
63
+ emr = Elasticity::EMR.new(ENV["aws_access_key_id"], ENV["aws_secret_key"])
64
+ jobflows = emr.describe_jobflows
65
+ p jobflows.map(&:name)
66
+
67
+ > ["Hive Test", "Pig Test", "Interactive Hadoop", "Interactive Hive"]
30
68
  </pre>
31
69
 
32
70
  == ModifyInstanceGroups ==
@@ -34,25 +72,26 @@ DescribeJobFlows returns detailed information as to the state of all jobs. Curr
34
72
  A job flow contains several "instance groups" of various types. These instances are where the work for your EMR task occurs. After a job flow has been created, you can find these instance groups in the AWS web UI by clicking on a job flow and then clicking on the "Instance Groups" tab.
35
73
 
36
74
  <pre>
37
- > emr = Elasticity::EMR.new(ENV["aws_access_key_id"], ENV["aws_secret_key"])
38
- > emr.modify_instance_groups({"ig-2T1HNUO61BG3O" => 3})
39
- >
75
+ emr = Elasticity::EMR.new(ENV["aws_access_key_id"], ENV["aws_secret_key"])
76
+ emr.modify_instance_groups({"ig-2T1HNUO61BG3O" => 3})
40
77
  </pre>
41
78
 
42
79
  If there's an error, you'll receive an ArgumentError containing the message from Amazon. For example if you attempt to modify an instance group that's part of a terminated job flow:
43
80
 
44
81
  <pre>
45
- > emr = Elasticity::EMR.new(ENV["aws_access_key_id"], ENV["aws_secret_key"])
46
- > emr.modify_instance_groups({"ig-some_terminated_group" => 3})
47
- ArgumentError: An instance group may only be modified when the job flow is running or waiting
82
+ emr = Elasticity::EMR.new(ENV["aws_access_key_id"], ENV["aws_secret_key"])
83
+ emr.modify_instance_groups({"ig-some_terminated_group" => 3})
84
+
85
+ > ArgumentError: An instance group may only be modified when the job flow is running or waiting
48
86
  </pre>
49
87
 
50
88
  Or if you attempt to increase the instance count of the MASTER instance group:
51
89
 
52
90
  <pre>
53
- > emr = Elasticity::EMR.new(ENV["aws_access_key_id"], ENV["aws_secret_key"])
54
- > emr.modify_instance_groups({"ig-some_terminated_group" => 3})
55
- ArgumentError: A master instance group may not be modified
91
+ emr = Elasticity::EMR.new(ENV["aws_access_key_id"], ENV["aws_secret_key"])
92
+ emr.modify_instance_groups({"ig-some_terminated_group" => 3})
93
+
94
+ > ArgumentError: A master instance group may not be modified
56
95
  </pre>
57
96
 
58
97
  == RunJobFlow ==
@@ -64,17 +103,17 @@ Or if you attempt to increase the instance count of the MASTER instance group:
64
103
  When the job flow '''exists''', you will receive no output. This is because Amazon does not return anything other than a 200 when you terminate a job flow :) You'll want to continuously poll with DescribeJobFlows to see when the job was actually terminated.
65
104
 
66
105
  <pre>
67
- > emr = Elasticity::EMR.new(ENV["aws_access_key_id"], ENV["aws_secret_key"])
68
- > emr.terminate_jobflows("j-BOWBV7884XD0")
69
- >
106
+ emr = Elasticity::EMR.new(ENV["aws_access_key_id"], ENV["aws_secret_key"])
107
+ emr.terminate_jobflows("j-BOWBV7884XD0")
70
108
  </pre>
71
109
 
72
110
  When the job flow '''doesn't exist''':
73
111
 
74
112
  <pre>
75
- > emr = Elasticity::EMR.new(ENV["aws_access_key_id"], ENV["aws_secret_key"])
76
- > emr.terminate_jobflows("no-flow")
77
- ArgumentError: Job flow 'no-flow' does not exist.
113
+ emr = Elasticity::EMR.new(ENV["aws_access_key_id"], ENV["aws_secret_key"])
114
+ emr.terminate_jobflows("no-flow")
115
+
116
+ > ArgumentError: Job flow 'no-flow' does not exist.
78
117
  </pre>
79
118
 
80
119
  = Direct Response Access =
@@ -82,9 +121,10 @@ When the job flow '''doesn't exist''':
82
121
  If you're fine with Elasticity's invocation wrapping and would prefer to get at the resulting XML rather than the wrapped response, throw a block our way and we'll yield the result. This still saves you the trouble of having to create the params and sign the request yet gives you direct access to the response XML for your parsing pleasure.
83
122
 
84
123
  <pre>
85
- > emr = Elasticity::EMR.new(ENV["aws_access_key_id"], ENV["aws_secret_key"])
86
- > emr.describe_jobflows{|xml| puts xml[0..77]}
87
- <DescribeJobFlowsResponse xmlns="http://elasticmapreduce.amazonaws.com/doc/200
124
+ emr = Elasticity::EMR.new(ENV["aws_access_key_id"], ENV["aws_secret_key"])
125
+ emr.describe_jobflows{|xml| puts xml[0..77]}
126
+
127
+ > <DescribeJobFlowsResponse xmlns="http://elasticmapreduce.amazonaws.com/doc/200
88
128
  </pre>
89
129
 
90
130
  = Direct Request/Response Access =
@@ -92,11 +132,12 @@ If you're fine with Elasticity's invocation wrapping and would prefer to get at
92
132
  If you're chomping at the bit to initiate some EMR functionality that isn't wrapped (or isn't wrapped in a way you prefer :) feel free to access the AWS EMR API directly by using <code>EMR.direct()</code>. You can find the allowed values in Amazon's EMR API [http://docs.amazonwebservices.com/ElasticMapReduce/latest/DeveloperGuide/index.html developer documentation].
93
133
 
94
134
  <pre>
95
- > emr = Elasticity::EMR.new(ENV["aws_access_key_id"], ENV["aws_secret_key"])
96
- > params = {"Operation" => "DescribeJobFlows"}
97
- > result_xml = emr.direct(params)
98
- > result_xml[0..78]
99
- <DescribeJobFlowsResponse xmlns="http://elasticmapreduce.amazonaws.com/doc/2009
135
+ emr = Elasticity::EMR.new(ENV["aws_access_key_id"], ENV["aws_secret_key"])
136
+ params = {"Operation" => "DescribeJobFlows"}
137
+ result_xml = emr.direct(params)
138
+ result_xml[0..78]
139
+
140
+ > <DescribeJobFlowsResponse xmlns="http://elasticmapreduce.amazonaws.com/doc/2009
100
141
  </pre>
101
142
 
102
143
  <!-- __NOTOC__ -->
@@ -15,6 +15,53 @@ module Elasticity
15
15
  JobFlow.from_members_nodeset(xml_doc.xpath("/DescribeJobFlowsResponse/DescribeJobFlowsResult/JobFlows/member"))
16
16
  end
17
17
 
18
+ # Adds a new group of instances to the specified jobflow. Elasticity maps a
19
+ # more Ruby-like syntax to the Amazon options. An exhaustive hash follows although
20
+ # not all of these options are required (or valid!) at once. Please see the
21
+ # EMR docs for details although even then you're going to need to experiment :)
22
+ #
23
+ # instance_group_config = {
24
+ # :bid_price => 5,
25
+ # :count => 1,
26
+ # :role => "TASK",
27
+ # :type => "m1.small",
28
+ # :market => "SPOT",
29
+ # :name => "Go Canucks Go!"
30
+ # }
31
+ #
32
+ # add_instance_groups takes an array of {}.
33
+ #
34
+ # Returns an array of the instance IDs that were created by the specified configs.
35
+ #
36
+ # ["ig-2GOVEN6HVJZID", "ig-1DU9M2UQMM051", "ig-3DZRW4Y2X4S", ...]
37
+ def add_instance_groups(jobflow_id, instance_group_configs)
38
+ params = {
39
+ "Operation" => "AddInstanceGroups",
40
+ "JobFlowId" => jobflow_id
41
+ }
42
+ instance_group_configs.each_with_index do |ig_config, index|
43
+ params.merge!("InstanceGroups.member.#{index+1}.BidPrice" => ig_config[:bid_price]) if ig_config[:bid_price]
44
+ params.merge!("InstanceGroups.member.#{index+1}.InstanceCount" => ig_config[:count]) if ig_config[:count]
45
+ params.merge!("InstanceGroups.member.#{index+1}.InstanceRole" => ig_config[:role]) if ig_config[:role]
46
+ params.merge!("InstanceGroups.member.#{index+1}.InstanceType" => ig_config[:type]) if ig_config[:type]
47
+ params.merge!("InstanceGroups.member.#{index+1}.Market" => ig_config[:market]) if ig_config[:market]
48
+ params.merge!("InstanceGroups.member.#{index+1}.Name" => ig_config[:name]) if ig_config[:name]
49
+ end
50
+ begin
51
+ aws_result = @aws_request.aws_emr_request(params)
52
+ xml_doc = Nokogiri::XML(aws_result)
53
+ xml_doc.remove_namespaces!
54
+ instance_group_ids = []
55
+ xml_doc.xpath("/AddInstanceGroupsResponse/AddInstanceGroupsResult/InstanceGroupIds/member").each do |member|
56
+ instance_group_ids << member.text
57
+ end
58
+ yield aws_result if block_given?
59
+ instance_group_ids
60
+ rescue RestClient::BadRequest => e
61
+ raise ArgumentError, parse_error_response(e.http_body)
62
+ end
63
+ end
64
+
18
65
  # Set the number of instances in the specified instance groups to the
19
66
  # specified counts. Note that this modifies the *request* count, which
20
67
  # is not the same as the *running* count. I.e. you request instances
@@ -22,7 +69,7 @@ module Elasticity
22
69
  #
23
70
  # Takes a {} of instance group IDs => desired instance count.
24
71
  #
25
- # {"ig-1" => 40, "ig-2" => 5", ...}
72
+ # {"ig-1" => 40, "ig-2" => 5, ...}
26
73
  def modify_instance_groups(instance_group_config)
27
74
  params = {"Operation" => "ModifyInstanceGroups"}
28
75
  instance_group_config.keys.each_with_index do |instance_group, index|
@@ -1,3 +1,3 @@
1
1
  module Elasticity
2
- VERSION = "0.4"
2
+ VERSION = "0.5"
3
3
  end
@@ -0,0 +1,38 @@
1
+ ---
2
+ - !ruby/struct:VCR::HTTPInteraction
3
+ request: !ruby/struct:VCR::Request
4
+ method: :get
5
+ uri: !ruby/regexp /^http:\/\/elasticmapreduce.amazonaws.com:80\/\?AWSAccessKeyId=AKIAI7HEMMNKGT6VFFSA&InstanceGroups.member.1.InstanceCount=1&InstanceGroups.member.1.InstanceRole=TASK&InstanceGroups.member.1.InstanceType=m1.small&InstanceGroups.member.1.Market=ON_DEMAND&InstanceGroups.member.1.Name=Go%20Canucks%20Go!&JobFlowId=j-OALI7TZTQMHX&Operation=AddInstanceGroups/
6
+ body:
7
+ headers:
8
+ accept:
9
+ - "*/*; q=0.5, application/xml"
10
+ accept-encoding:
11
+ - gzip, deflate
12
+ response: !ruby/struct:VCR::Response
13
+ status: !ruby/struct:VCR::ResponseStatus
14
+ code: 200
15
+ message: OK
16
+ headers:
17
+ x-amzn-requestid:
18
+ - ddd0d158-67eb-11e0-ba06-2b5c43005be2
19
+ content-type:
20
+ - text/xml
21
+ date:
22
+ - Sat, 16 Apr 2011 05:39:15 GMT
23
+ content-length:
24
+ - "411"
25
+ body: |
26
+ <AddInstanceGroupsResponse xmlns="http://elasticmapreduce.amazonaws.com/doc/2009-03-31">
27
+ <AddInstanceGroupsResult>
28
+ <JobFlowId>j-OALI7TZTQMHX</JobFlowId>
29
+ <InstanceGroupIds>
30
+ <member>ig-2GOVEN6HVJZID</member>
31
+ </InstanceGroupIds>
32
+ </AddInstanceGroupsResult>
33
+ <ResponseMetadata>
34
+ <RequestId>ddd0d158-67eb-11e0-ba06-2b5c43005be2</RequestId>
35
+ </ResponseMetadata>
36
+ </AddInstanceGroupsResponse>
37
+
38
+ http_version: "1.1"
@@ -0,0 +1,35 @@
1
+ ---
2
+ - !ruby/struct:VCR::HTTPInteraction
3
+ request: !ruby/struct:VCR::Request
4
+ method: :get
5
+ uri: !ruby/regexp /^http:\/\/elasticmapreduce.amazonaws.com:80\/\?AWSAccessKeyId=AKIAI7HEMMNKGT6VFFSA&InstanceGroups.member.1.BidPrice=0&InstanceGroups.member.1.InstanceCount=1&InstanceGroups.member.1.InstanceRole=TASK&InstanceGroups.member.1.InstanceType=m1.small&InstanceGroups.member.1.Market=ON_DEMAND&InstanceGroups.member.1.Name=Go%20Canucks%20Go!&JobFlowId=j-19WDDS68ZUENP&Operation=AddInstanceGroups/
6
+ body:
7
+ headers:
8
+ accept:
9
+ - "*/*; q=0.5, application/xml"
10
+ accept-encoding:
11
+ - gzip, deflate
12
+ response: !ruby/struct:VCR::Response
13
+ status: !ruby/struct:VCR::ResponseStatus
14
+ code: 400
15
+ message: Bad Request
16
+ headers:
17
+ x-amzn-requestid:
18
+ - 0c8d744d-67ea-11e0-bf8a-ed57a5465c87
19
+ content-type:
20
+ - text/xml
21
+ date:
22
+ - Sat, 16 Apr 2011 05:26:15 GMT
23
+ content-length:
24
+ - "337"
25
+ body: |
26
+ <ErrorResponse xmlns="http://elasticmapreduce.amazonaws.com/doc/2009-03-31">
27
+ <Error>
28
+ <Type>Sender</Type>
29
+ <Code>ValidationError</Code>
30
+ <Message>Task instance group already exists in the job flow, cannot add more task groups</Message>
31
+ </Error>
32
+ <RequestId>0c8d744d-67ea-11e0-bf8a-ed57a5465c87</RequestId>
33
+ </ErrorResponse>
34
+
35
+ http_version: "1.1"
@@ -2,6 +2,118 @@ require 'spec_helper'
2
2
 
3
3
  describe Elasticity::EMR do
4
4
 
5
+ describe "#add_instance_groups" do
6
+
7
+ describe "integration happy path" do
8
+
9
+ context "when properly specified" do
10
+ use_vcr_cassette "add_instance_groups/one_group_successful", :record => :none
11
+ it "should add the instance groups" do
12
+ emr = Elasticity::EMR.new(ENV["aws_access_key_id"], ENV["aws_secret_key"])
13
+ instance_group_config = {
14
+ :count => 1,
15
+ :role => "TASK",
16
+ :type => "m1.small",
17
+ :market => "ON_DEMAND",
18
+ :name => "Go Canucks Go!"
19
+ }
20
+ instance_group_ids = emr.add_instance_groups("j-OALI7TZTQMHX", [instance_group_config])
21
+ instance_group_ids.should == ["ig-2GOVEN6HVJZID"]
22
+ end
23
+ end
24
+
25
+ context "when improperly specified" do
26
+ use_vcr_cassette "add_instance_groups/one_group_unsuccessful", :record => :none
27
+ it "should add the instance groups" do
28
+ emr = Elasticity::EMR.new(ENV["aws_access_key_id"], ENV["aws_secret_key"])
29
+ instance_group_config = {
30
+ :bid_price => 0,
31
+ :count => 1,
32
+ :role => "TASK",
33
+ :type => "m1.small",
34
+ :market => "ON_DEMAND",
35
+ :name => "Go Canucks Go!"
36
+ }
37
+ lambda {
38
+ emr.add_instance_groups("j-19WDDS68ZUENP", [instance_group_config])
39
+ }.should raise_error(ArgumentError, "Task instance group already exists in the job flow, cannot add more task groups")
40
+ end
41
+ end
42
+
43
+ end
44
+
45
+ describe "unit tests" do
46
+
47
+ context "when multiple instance groups are specified" do
48
+ before do
49
+ @add_instance_groups_xml = <<-ADD_GROUPS
50
+ <AddInstanceGroupsResponse xmlns="http://elasticmapreduce.amazonaws.com/doc/2009-03-31">
51
+ <AddInstanceGroupsResult>
52
+ <JobFlowId>j-OALI7TZTQMHX</JobFlowId>
53
+ <InstanceGroupIds>
54
+ <member>ig-1</member>
55
+ <member>ig-2</member>
56
+ <member>ig-3</member>
57
+ </InstanceGroupIds>
58
+ </AddInstanceGroupsResult>
59
+ </AddInstanceGroupsResponse>
60
+ ADD_GROUPS
61
+ end
62
+
63
+ it "should iterate over them and send the correct params to AWS" do
64
+ instance_group_configs = [
65
+ {:type=>"m1.small", :role=>"CORE", :market=>"ON_DEMAND", :count=>1, :name=>"Go Canucks Go!", :bid_price=>0},
66
+ {:type=>"m1.small", :role=>"CORE", :market=>"ON_DEMAND", :count=>1, :name=>"Go Canucks Go!", :bid_price=>0},
67
+ ]
68
+ aws_request = Elasticity::AwsRequest.new("aws_access_key_id", "aws_secret_key")
69
+ aws_request.should_receive(:aws_emr_request).with({
70
+ "Operation" => "AddInstanceGroups",
71
+ "InstanceGroups.member.1.Name"=>"Go Canucks Go!",
72
+ "InstanceGroups.member.1.InstanceRole"=>"CORE",
73
+ "InstanceGroups.member.1.InstanceCount"=>1,
74
+ "InstanceGroups.member.1.BidPrice"=>0,
75
+ "InstanceGroups.member.1.InstanceType"=>"m1.small",
76
+ "InstanceGroups.member.1.Market"=>"ON_DEMAND",
77
+ "InstanceGroups.member.2.Name"=>"Go Canucks Go!",
78
+ "InstanceGroups.member.2.InstanceRole"=>"CORE",
79
+ "InstanceGroups.member.2.InstanceCount"=>1,
80
+ "InstanceGroups.member.2.BidPrice"=>0,
81
+ "InstanceGroups.member.2.InstanceType"=>"m1.small",
82
+ "InstanceGroups.member.2.Market"=>"ON_DEMAND",
83
+ "JobFlowId"=>"j-19WDDS68ZUENP"
84
+ })
85
+ Elasticity::AwsRequest.should_receive(:new).and_return(aws_request)
86
+ emr = Elasticity::EMR.new("aws_access_key_id", "aws_secret_key")
87
+ emr.add_instance_groups("j-19WDDS68ZUENP", instance_group_configs)
88
+ end
89
+
90
+ it "should return an array of the instance groups created" do
91
+ aws_request = Elasticity::AwsRequest.new("aws_access_key_id", "aws_secret_key")
92
+ aws_request.should_receive(:aws_emr_request).and_return(@add_instance_groups_xml)
93
+ Elasticity::AwsRequest.should_receive(:new).and_return(aws_request)
94
+ emr = Elasticity::EMR.new("aws_access_key_id", "aws_secret_key")
95
+ emr.add_instance_groups("", []).should == ["ig-1", "ig-2", "ig-3"]
96
+ end
97
+ end
98
+
99
+ context "when a block is provided" do
100
+ it "should yield the XML result" do
101
+ aws_request = Elasticity::AwsRequest.new("aws_access_key_id", "aws_secret_key")
102
+ aws_request.should_receive(:aws_emr_request).and_return("AWS XML")
103
+ Elasticity::AwsRequest.should_receive(:new).and_return(aws_request)
104
+ emr = Elasticity::EMR.new("aws_access_key_id", "aws_secret_key")
105
+ xml_result = nil
106
+ emr.add_instance_groups("", []) do |xml|
107
+ xml_result = xml
108
+ end
109
+ xml_result.should == "AWS XML"
110
+ end
111
+ end
112
+
113
+ end
114
+
115
+ end
116
+
5
117
  describe "#describe_jobflows" do
6
118
 
7
119
  describe "integration happy path" do
@@ -53,14 +165,14 @@ describe Elasticity::EMR do
53
165
  context "when a block is provided" do
54
166
  it "should yield the XML result" do
55
167
  aws_request = Elasticity::AwsRequest.new("aws_access_key_id", "aws_secret_key")
56
- aws_request.should_receive(:aws_emr_request).with({"Operation" => "DescribeJobFlows"}).and_return(@describe_jobflows_xml)
168
+ aws_request.should_receive(:aws_emr_request).and_return("describe!")
57
169
  Elasticity::AwsRequest.should_receive(:new).and_return(aws_request)
58
170
  emr = Elasticity::EMR.new("aws_access_key_id", "aws_secret_key")
59
171
  xml_result = nil
60
172
  emr.describe_jobflows do |xml|
61
173
  xml_result = xml
62
174
  end
63
- xml_result.should == @describe_jobflows_xml
175
+ xml_result.should == "describe!"
64
176
  end
65
177
  end
66
178
  end
@@ -82,7 +194,6 @@ describe Elasticity::EMR do
82
194
  describe "unit tests" do
83
195
 
84
196
  context "when the jobflow exists" do
85
-
86
197
  before do
87
198
  @terminate_jobflows_xml = <<-RESPONSE
88
199
  <TerminateJobFlowsResponse xmlns="http://elasticmapreduce.amazonaws.com/doc/2009-03-31">
@@ -92,7 +203,6 @@ describe Elasticity::EMR do
92
203
  </TerminateJobFlowsResponse>
93
204
  RESPONSE
94
205
  end
95
-
96
206
  it "should terminate the specific jobflow" do
97
207
  aws_request = Elasticity::AwsRequest.new("aws_access_key_id", "aws_secret_key")
98
208
  aws_request.should_receive(:aws_emr_request).with({
@@ -103,24 +213,6 @@ describe Elasticity::EMR do
103
213
  emr = Elasticity::EMR.new("aws_access_key_id", "aws_secret_key")
104
214
  emr.terminate_jobflows("j-1")
105
215
  end
106
-
107
- context "when a block is given" do
108
- it "should yield the XML result" do
109
- aws_request = Elasticity::AwsRequest.new("aws_access_key_id", "aws_secret_key")
110
- aws_request.should_receive(:aws_emr_request).with({
111
- "Operation" => "TerminateJobFlows",
112
- "JobFlowIds.member.1" => "j-1"
113
- }).and_return(@terminate_jobflows_xml)
114
- Elasticity::AwsRequest.should_receive(:new).and_return(aws_request)
115
- emr = Elasticity::EMR.new("aws_access_key_id", "aws_secret_key")
116
- xml_result = nil
117
- emr.terminate_jobflows("j-1") do |xml|
118
- xml_result = xml
119
- end
120
- xml_result.should == @terminate_jobflows_xml
121
- end
122
- end
123
-
124
216
  end
125
217
 
126
218
  context "when the jobflow does not exist" do
@@ -135,6 +227,20 @@ describe Elasticity::EMR do
135
227
  end
136
228
  end
137
229
 
230
+ context "when a block is given" do
231
+ it "should yield the XML result" do
232
+ aws_request = Elasticity::AwsRequest.new("aws_access_key_id", "aws_secret_key")
233
+ aws_request.should_receive(:aws_emr_request).and_return("terminated!")
234
+ Elasticity::AwsRequest.should_receive(:new).and_return(aws_request)
235
+ emr = Elasticity::EMR.new("aws_access_key_id", "aws_secret_key")
236
+ xml_result = nil
237
+ emr.terminate_jobflows("j-1") do |xml|
238
+ xml_result = xml
239
+ end
240
+ xml_result.should == "terminated!"
241
+ end
242
+ end
243
+
138
244
  end
139
245
  end
140
246
 
@@ -168,25 +274,16 @@ describe Elasticity::EMR do
168
274
  end
169
275
 
170
276
  context "when a block is given" do
171
- before do
172
- @modify_instance_groups_xml = <<-RESPONSE
173
- <ModifyInstanceGroupsResponse xmlns="http://elasticmapreduce.amazonaws.com/doc/2009-03-31">
174
- <ResponseMetadata>
175
- <RequestId>4ef75373-659c-11e0-bdf6-e3d62a364c28</RequestId>
176
- </ResponseMetadata>
177
- </ModifyInstanceGroupsResponse>
178
- RESPONSE
179
- end
180
277
  it "should yield the XML result" do
181
278
  aws_request = Elasticity::AwsRequest.new("aws_access_key_id", "aws_secret_key")
182
- aws_request.should_receive(:aws_emr_request).and_return(@modify_instance_groups_xml)
279
+ aws_request.should_receive(:aws_emr_request).and_return("xml result!")
183
280
  Elasticity::AwsRequest.should_receive(:new).and_return(aws_request)
184
281
  emr = Elasticity::EMR.new("aws_access_key_id", "aws_secret_key")
185
282
  xml_result = nil
186
- emr.modify_instance_groups({"ig-1" => 2}) do |xml|
283
+ emr.modify_instance_groups({"ig-1" => 2}) do |xml|
187
284
  xml_result = xml
188
285
  end
189
- xml_result.should == @modify_instance_groups_xml
286
+ xml_result.should == "xml result!"
190
287
  end
191
288
  end
192
289
 
metadata CHANGED
@@ -1,12 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: elasticity
3
3
  version: !ruby/object:Gem::Version
4
- hash: 3
4
+ hash: 1
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 4
9
- version: "0.4"
8
+ - 5
9
+ version: "0.5"
10
10
  platform: ruby
11
11
  authors:
12
12
  - Robert Slifka
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-04-13 00:00:00 -07:00
17
+ date: 2011-04-16 00:00:00 -07:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -128,6 +128,8 @@ files:
128
128
  - lib/elasticity/emr.rb
129
129
  - lib/elasticity/job_flow.rb
130
130
  - lib/elasticity/version.rb
131
+ - spec/fixtures/vcr_cassettes/add_instance_groups/one_group_successful.yml
132
+ - spec/fixtures/vcr_cassettes/add_instance_groups/one_group_unsuccessful.yml
131
133
  - spec/fixtures/vcr_cassettes/describe_jobflows/all_jobflows.yml
132
134
  - spec/fixtures/vcr_cassettes/direct/terminate_jobflow.yml
133
135
  - spec/fixtures/vcr_cassettes/modify_instance_groups/set_instances_to_3.yml
@@ -171,6 +173,8 @@ signing_key:
171
173
  specification_version: 3
172
174
  summary: Programmatic access to Amazon's Elastic Map Reduce service.
173
175
  test_files:
176
+ - spec/fixtures/vcr_cassettes/add_instance_groups/one_group_successful.yml
177
+ - spec/fixtures/vcr_cassettes/add_instance_groups/one_group_unsuccessful.yml
174
178
  - spec/fixtures/vcr_cassettes/describe_jobflows/all_jobflows.yml
175
179
  - spec/fixtures/vcr_cassettes/direct/terminate_jobflow.yml
176
180
  - spec/fixtures/vcr_cassettes/modify_instance_groups/set_instances_to_3.yml