elasticity 5.0.1 → 5.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,191 @@
1
+ describe Elasticity::AwsSession do
2
+
3
+ before do
4
+ Timecop.freeze(Time.at(1302461096))
5
+ end
6
+
7
+ after do
8
+ Timecop.return
9
+ end
10
+
11
+ subject do
12
+ Elasticity::AwsSession.new('access', 'secret')
13
+ end
14
+
15
+ describe '#initialize' do
16
+
17
+ context 'when access and/or secret keys are provided' do
18
+ it 'should set them to the provided values' do
19
+ subject.access_key.should == 'access'
20
+ subject.secret_key.should == 'secret'
21
+ subject.region.should == 'us-east-1'
22
+ end
23
+ end
24
+
25
+ context 'when :region is nil' do
26
+ it 'should be an error' do
27
+ expect {
28
+ Elasticity::AwsSession.new('_', '_', :region => nil)
29
+ }.to raise_error Elasticity::MissingRegionError, 'A valid :region is required to connect to EMR'
30
+ end
31
+ end
32
+
33
+ context 'when :region is specified' do
34
+ Elasticity::AwsSession.new('_', '_', :region => 'TEST_REGION').region.should == 'TEST_REGION'
35
+ end
36
+
37
+ context 'when either access or secret key is not provided or nil' do
38
+
39
+ context 'when the proper environment variables are set' do
40
+
41
+ context 'when access and secret key are not provided' do
42
+ let(:default_values) { Elasticity::AwsSession.new }
43
+ before do
44
+ ENV.stub(:[]).with('AWS_ACCESS_KEY_ID').and_return('ENV_ACCESS')
45
+ ENV.stub(:[]).with('AWS_SECRET_ACCESS_KEY').and_return('ENV_SECRET')
46
+ end
47
+ it 'should set access and secret keys' do
48
+ default_values.access_key.should == 'ENV_ACCESS'
49
+ default_values.secret_key.should == 'ENV_SECRET'
50
+ end
51
+ end
52
+
53
+ context 'when access and secret key are nil' do
54
+ let(:nil_values) { Elasticity::AwsSession.new(nil, nil) }
55
+ before do
56
+ ENV.stub(:[]).with('AWS_ACCESS_KEY_ID').and_return('ENV_ACCESS')
57
+ ENV.stub(:[]).with('AWS_SECRET_ACCESS_KEY').and_return('ENV_SECRET')
58
+ end
59
+ it 'should set access and secret keys' do
60
+ nil_values.access_key.should == 'ENV_ACCESS'
61
+ nil_values.secret_key.should == 'ENV_SECRET'
62
+ end
63
+ end
64
+
65
+ end
66
+
67
+ context 'when the environment variables are not set' do
68
+ let(:missing_something) { Elasticity::AwsSession.new }
69
+ context 'when the access key is not set' do
70
+ before do
71
+ ENV.stub(:[]).with('AWS_ACCESS_KEY_ID').and_return(nil)
72
+ ENV.stub(:[]).with('AWS_SECRET_ACCESS_KEY').and_return('_')
73
+ end
74
+ it 'should raise an error' do
75
+ expect {
76
+ missing_something.access_key
77
+ }.to raise_error(Elasticity::MissingKeyError, 'Please provide an access key or set AWS_ACCESS_KEY_ID.')
78
+ end
79
+ end
80
+ context 'when the secret key is not set' do
81
+ before do
82
+ ENV.stub(:[]).with('AWS_ACCESS_KEY_ID').and_return('_')
83
+ ENV.stub(:[]).with('AWS_SECRET_ACCESS_KEY').and_return(nil)
84
+ end
85
+ it 'should raise an error' do
86
+ expect {
87
+ missing_something.access_key
88
+ }.to raise_error(Elasticity::MissingKeyError, 'Please provide a secret key or set AWS_SECRET_ACCESS_KEY.')
89
+ end
90
+ end
91
+ end
92
+
93
+ end
94
+
95
+ end
96
+
97
+ describe '#host' do
98
+
99
+ context 'when the region is not specified' do
100
+ its(:host) { should == 'elasticmapreduce.us-east-1.amazonaws.com' }
101
+ end
102
+
103
+ context 'when the region is specified' do
104
+ let(:request_with_region) do
105
+ Elasticity::AwsSession.new('_', '_', {:region => 'us-west-1'})
106
+ end
107
+ it 'should incorporate the region into the hostname' do
108
+ request_with_region.host.should == 'elasticmapreduce.us-west-1.amazonaws.com'
109
+ end
110
+ end
111
+
112
+ end
113
+
114
+ describe '#submit' do
115
+
116
+ context 'when there is not an error with the request' do
117
+ before do
118
+ @request = Elasticity::AwsRequestV4.new(subject, {})
119
+ @request.should_receive(:url).and_return('TEST_URL')
120
+ @request.should_receive(:payload).and_return('TEST_PAYLOAD')
121
+ @request.should_receive(:headers).and_return('TEST_HEADERS')
122
+
123
+ Elasticity::AwsRequestV4.should_receive(:new).with(subject, {}).and_return(@request)
124
+ RestClient.should_receive(:post).with('TEST_URL', 'TEST_PAYLOAD', 'TEST_HEADERS')
125
+ end
126
+
127
+ it 'should POST a properly assembled request' do
128
+ subject.submit({})
129
+ end
130
+ end
131
+
132
+ context 'when there is an EMR error with the request' do
133
+ let(:error_message) { 'ERROR_MESSAGE' }
134
+ let(:error_xml) do
135
+ <<-XML
136
+ <ErrorResponse xmlns="http://elasticmapreduce.amazonaws.com/doc/2009-03-31">
137
+ <Error>
138
+ <Message>#{error_message}</Message>
139
+ </Error>
140
+ </ErrorResponse>
141
+ XML
142
+ end
143
+ let(:error) do
144
+ RestClient::BadRequest.new.tap do |error|
145
+ error.stub(:http_body => error_xml)
146
+ end
147
+ end
148
+
149
+ it 'should raise an Argument error with the body of the error' do
150
+ RestClient.should_receive(:post).and_raise(error)
151
+ expect {
152
+ subject.submit({})
153
+ }.to raise_error(ArgumentError, error_message)
154
+ end
155
+ end
156
+
157
+ end
158
+
159
+ describe '#==' do
160
+
161
+ describe 'basic equality checks with subject' do
162
+ let(:same_object) { subject }
163
+ let(:same_values) { Elasticity::AwsSession.new('access', 'secret', {}) }
164
+ let(:diff_type) { Object.new }
165
+
166
+ it { should == same_object }
167
+ it { should == same_values }
168
+ it { should_not == diff_type }
169
+ end
170
+
171
+ describe 'deep comparisons' do
172
+
173
+ it 'should fail on access key check' do
174
+ Elasticity::AwsSession.new('access', '_').should_not == Elasticity::AwsSession.new('_', '_')
175
+ end
176
+
177
+ it 'should fail on secret key check' do
178
+ Elasticity::AwsSession.new('_', 'secret').should_not == Elasticity::AwsSession.new('_', '_')
179
+ end
180
+
181
+ it 'should fail on host check' do
182
+ aws1 = Elasticity::AwsSession.new('_', '_', :region => 'us-east-1')
183
+ aws2 = Elasticity::AwsSession.new('_', '_', :region => 'us-west-1')
184
+ aws1.should_not == aws2
185
+ end
186
+
187
+ end
188
+
189
+ end
190
+
191
+ end
@@ -0,0 +1,105 @@
1
+ describe Elasticity::AwsUtils do
2
+
3
+ describe '.convert_ruby_to_aws_v4' do
4
+ it 'should convert the params' do
5
+ add_jobflow_steps_params = {
6
+ :job_flow_id => 'j-1',
7
+ :string_values => [
8
+ 'value1', 'value2'
9
+ ],
10
+ :steps => [
11
+ {
12
+ :action_on_failure => 'CONTINUE',
13
+ :name => 'First New Job Step',
14
+ :hadoop_jar_step => {
15
+ :args => %w(arg1 arg2 arg3),
16
+ :jar => 'first_step.jar',
17
+ :main_class => 'first_class.jar'
18
+ }
19
+ },
20
+ {
21
+ :action_on_failure => 'CANCEL_AND_WAIT',
22
+ :name => 'Second New Job Step',
23
+ :hadoop_jar_step => {
24
+ :args => %w(arg4 arg5 arg6),
25
+ :jar => 'second_step.jar',
26
+ :main_class => 'second_class.jar'
27
+ }
28
+ }
29
+ ]
30
+ }
31
+ expected_result = {
32
+ 'JobFlowId' => 'j-1',
33
+ 'StringValues' => ['value1', 'value2'],
34
+ 'Steps' => [
35
+ {
36
+ 'ActionOnFailure' => 'CONTINUE',
37
+ 'Name' => 'First New Job Step',
38
+ 'HadoopJarStep' => {
39
+ 'Args' => %w(arg1 arg2 arg3),
40
+ 'Jar' => 'first_step.jar',
41
+ 'MainClass' => 'first_class.jar'
42
+ }
43
+ },
44
+ {
45
+ 'ActionOnFailure' => 'CANCEL_AND_WAIT',
46
+ 'Name' => 'Second New Job Step',
47
+ 'HadoopJarStep' => {
48
+ 'Args' => %w(arg4 arg5 arg6),
49
+ 'Jar' => 'second_step.jar',
50
+ 'MainClass' => 'second_class.jar'
51
+ }
52
+ }
53
+ ]
54
+ }
55
+ Elasticity::AwsUtils.send(:convert_ruby_to_aws_v4, add_jobflow_steps_params).should == expected_result
56
+ end
57
+ end
58
+
59
+ describe '.convert_ruby_to_aws' do
60
+ it 'should convert the params' do
61
+ add_jobflow_steps_params = {
62
+ :job_flow_id => 'j-1',
63
+ :steps => [
64
+ {
65
+ :action_on_failure => 'CONTINUE',
66
+ :name => 'First New Job Step',
67
+ :hadoop_jar_step => {
68
+ :args => %w(arg1 arg2 arg3),
69
+ :jar => 'first_step.jar',
70
+ :main_class => 'first_class.jar'
71
+ }
72
+ },
73
+ {
74
+ :action_on_failure => 'CANCEL_AND_WAIT',
75
+ :name => 'Second New Job Step',
76
+ :hadoop_jar_step => {
77
+ :args => %w(arg4 arg5 arg6),
78
+ :jar => 'second_step.jar',
79
+ :main_class => 'second_class.jar'
80
+ }
81
+ }
82
+ ]
83
+ }
84
+ expected_result = {
85
+ 'JobFlowId' => 'j-1',
86
+ 'Steps.member.1.Name' => 'First New Job Step',
87
+ 'Steps.member.1.ActionOnFailure' => 'CONTINUE',
88
+ 'Steps.member.1.HadoopJarStep.Jar' => 'first_step.jar',
89
+ 'Steps.member.1.HadoopJarStep.MainClass' => 'first_class.jar',
90
+ 'Steps.member.1.HadoopJarStep.Args.member.1' => 'arg1',
91
+ 'Steps.member.1.HadoopJarStep.Args.member.2' => 'arg2',
92
+ 'Steps.member.1.HadoopJarStep.Args.member.3' => 'arg3',
93
+ 'Steps.member.2.Name' => 'Second New Job Step',
94
+ 'Steps.member.2.ActionOnFailure' => 'CANCEL_AND_WAIT',
95
+ 'Steps.member.2.HadoopJarStep.Jar' => 'second_step.jar',
96
+ 'Steps.member.2.HadoopJarStep.MainClass' => 'second_class.jar',
97
+ 'Steps.member.2.HadoopJarStep.Args.member.1' => 'arg4',
98
+ 'Steps.member.2.HadoopJarStep.Args.member.2' => 'arg5',
99
+ 'Steps.member.2.HadoopJarStep.Args.member.3' => 'arg6'
100
+ }
101
+ Elasticity::AwsUtils.send(:convert_ruby_to_aws, add_jobflow_steps_params).should == expected_result
102
+ end
103
+ end
104
+
105
+ end
@@ -7,7 +7,7 @@ describe Elasticity::EMR do
7
7
  describe '.new' do
8
8
 
9
9
  context 'when arguments are provided' do
10
- its(:aws_request) { should == Elasticity::AwsRequest.new('ACCESS', 'SECRET', {}) }
10
+ its(:aws_request) { should == Elasticity::AwsSession.new('ACCESS', 'SECRET', {}) }
11
11
  end
12
12
 
13
13
  context 'when arguments are not provided' do
@@ -17,7 +17,7 @@ describe Elasticity::EMR do
17
17
  end
18
18
  it 'should use environment variables' do
19
19
  emr = Elasticity::EMR.new
20
- emr.aws_request.should == Elasticity::AwsRequest.new('ENV_ACCESS', 'ENV_SECRET', {})
20
+ emr.aws_request.should == Elasticity::AwsSession.new('ENV_ACCESS', 'ENV_SECRET', {})
21
21
  end
22
22
  end
23
23
 
@@ -26,7 +26,7 @@ describe Elasticity::EMR do
26
26
  describe '#add_instance_groups' do
27
27
 
28
28
  it 'should send the correct params to AWS' do
29
- Elasticity::AwsRequest.any_instance.should_receive(:submit).with({
29
+ Elasticity::AwsSession.any_instance.should_receive(:submit).with({
30
30
  :operation => 'AddInstanceGroups',
31
31
  :job_flow_id => 'JOBFLOW_ID',
32
32
  :instance_groups => ['INSTANCE_GROUP_CONFIGS']
@@ -51,7 +51,7 @@ describe Elasticity::EMR do
51
51
  end
52
52
 
53
53
  it 'should return an array of the new instance groups IDs' do
54
- Elasticity::AwsRequest.any_instance.should_receive(:submit).and_return(aws_response)
54
+ Elasticity::AwsSession.any_instance.should_receive(:submit).and_return(aws_response)
55
55
  subject.add_instance_groups('', []).should == ['ig-1', 'ig-2', 'ig-3']
56
56
  end
57
57
  end
@@ -59,7 +59,7 @@ describe Elasticity::EMR do
59
59
  context 'when a block is given' do
60
60
  let(:result) { 'RESULT' }
61
61
  it 'should yield the submission results' do
62
- Elasticity::AwsRequest.any_instance.should_receive(:submit).and_return(result)
62
+ Elasticity::AwsSession.any_instance.should_receive(:submit).and_return(result)
63
63
  subject.add_instance_groups('', []) do |xml|
64
64
  xml.should == 'RESULT'
65
65
  end
@@ -71,7 +71,7 @@ describe Elasticity::EMR do
71
71
  describe '#add_jobflow_steps' do
72
72
 
73
73
  it 'should add the specified steps to the job flow' do
74
- Elasticity::AwsRequest.any_instance.should_receive(:submit).with({
74
+ Elasticity::AwsSession.any_instance.should_receive(:submit).with({
75
75
  :operation => 'AddJobFlowSteps',
76
76
  :job_flow_id => 'JOBFLOW_ID',
77
77
  :steps => ['_']
@@ -82,7 +82,7 @@ describe Elasticity::EMR do
82
82
  context 'when a block is given' do
83
83
  let(:result) { 'RESULT' }
84
84
  it 'should yield the submission results' do
85
- Elasticity::AwsRequest.any_instance.should_receive(:submit).and_return(result)
85
+ Elasticity::AwsSession.any_instance.should_receive(:submit).and_return(result)
86
86
  subject.add_jobflow_steps('', {}) do |xml|
87
87
  xml.should == 'RESULT'
88
88
  end
@@ -121,14 +121,14 @@ describe Elasticity::EMR do
121
121
  end
122
122
 
123
123
  it 'should return an array of properly populated JobFlowStatusES' do
124
- Elasticity::AwsRequest.any_instance.should_receive(:submit).and_return(describe_jobflows_xml)
124
+ Elasticity::AwsSession.any_instance.should_receive(:submit).and_return(describe_jobflows_xml)
125
125
  jobflow_statuses = subject.describe_jobflows
126
126
  jobflow_statuses.map(&:name).should == ['Pig Job', 'Hive Job']
127
127
  jobflow_statuses.map(&:class).should == [Elasticity::JobFlowStatus, Elasticity::JobFlowStatus]
128
128
  end
129
129
 
130
130
  it 'should describe all jobflows' do
131
- Elasticity::AwsRequest.any_instance.should_receive(:submit).with({
131
+ Elasticity::AwsSession.any_instance.should_receive(:submit).with({
132
132
  :operation => 'DescribeJobFlows'
133
133
  })
134
134
  subject.describe_jobflows
@@ -136,7 +136,7 @@ describe Elasticity::EMR do
136
136
 
137
137
  context 'when additional parameters are provided' do
138
138
  it 'should pass them through' do
139
- Elasticity::AwsRequest.any_instance.should_receive(:submit).with({
139
+ Elasticity::AwsSession.any_instance.should_receive(:submit).with({
140
140
  :CreatedBefore => '2011-10-04',
141
141
  :operation => 'DescribeJobFlows'
142
142
  })
@@ -147,7 +147,7 @@ describe Elasticity::EMR do
147
147
  context 'when a block is given' do
148
148
  let(:result) { 'RESULT' }
149
149
  it 'should yield the submission results' do
150
- Elasticity::AwsRequest.any_instance.should_receive(:submit).and_return(result)
150
+ Elasticity::AwsSession.any_instance.should_receive(:submit).and_return(result)
151
151
  subject.describe_jobflows do |xml|
152
152
  xml.should == 'RESULT'
153
153
  end
@@ -178,7 +178,7 @@ describe Elasticity::EMR do
178
178
  }
179
179
 
180
180
  it 'should describe the specified jobflow' do
181
- Elasticity::AwsRequest.any_instance.should_receive(:submit).with({
181
+ Elasticity::AwsSession.any_instance.should_receive(:submit).with({
182
182
  :operation => 'DescribeJobFlows',
183
183
  :job_flow_ids => ['j-3UN6WX5RRO2AG']
184
184
  })
@@ -186,7 +186,7 @@ describe Elasticity::EMR do
186
186
  end
187
187
 
188
188
  it 'should return a properly populated JobFlowStatus' do
189
- Elasticity::AwsRequest.any_instance.should_receive(:submit).and_return(describe_jobflows_xml)
189
+ Elasticity::AwsSession.any_instance.should_receive(:submit).and_return(describe_jobflows_xml)
190
190
  jobflow_status = subject.describe_jobflow('_')
191
191
  jobflow_status.should be_a Elasticity::JobFlowStatus
192
192
  jobflow_status.jobflow_id.should == 'j-3UN6WX5RRO2AG'
@@ -195,7 +195,7 @@ describe Elasticity::EMR do
195
195
  context 'when a block is given' do
196
196
  let(:result) { 'RESULT' }
197
197
  it 'should yield the submission results' do
198
- Elasticity::AwsRequest.any_instance.should_receive(:submit).and_return(result)
198
+ Elasticity::AwsSession.any_instance.should_receive(:submit).and_return(result)
199
199
  subject.describe_jobflow('') do |xml|
200
200
  xml.should == 'RESULT'
201
201
  end
@@ -218,7 +218,7 @@ describe Elasticity::EMR do
218
218
  describe '#modify_instance_groups' do
219
219
 
220
220
  it 'should modify the specified instance groups' do
221
- Elasticity::AwsRequest.any_instance.should_receive(:submit).with({
221
+ Elasticity::AwsSession.any_instance.should_receive(:submit).with({
222
222
  :operation => 'ModifyInstanceGroups',
223
223
  :instance_groups => [{
224
224
  :instance_group_id => 'ig-2T1HNUO61BG3O',
@@ -231,7 +231,7 @@ describe Elasticity::EMR do
231
231
  context 'when a block is given' do
232
232
  let(:result) { '_' }
233
233
  it 'should yield the submission results' do
234
- Elasticity::AwsRequest.any_instance.should_receive(:submit).and_return(result)
234
+ Elasticity::AwsSession.any_instance.should_receive(:submit).and_return(result)
235
235
  subject.modify_instance_groups({}) do |xml|
236
236
  xml.should == '_'
237
237
  end
@@ -243,7 +243,7 @@ describe Elasticity::EMR do
243
243
  describe '#run_jobflow' do
244
244
 
245
245
  it 'should start the specified job flow' do
246
- Elasticity::AwsRequest.any_instance.should_receive(:submit).with({
246
+ Elasticity::AwsSession.any_instance.should_receive(:submit).with({
247
247
  :operation => 'RunJobFlow',
248
248
  :jobflow_params => '_'
249
249
  })
@@ -265,7 +265,7 @@ describe Elasticity::EMR do
265
265
  end
266
266
 
267
267
  it 'should return the ID of the running job flow' do
268
- Elasticity::AwsRequest.any_instance.should_receive(:submit).and_return(jobflow_xml_response)
268
+ Elasticity::AwsSession.any_instance.should_receive(:submit).and_return(jobflow_xml_response)
269
269
  subject.run_job_flow({}).should == 'j-G6N5HA528AD4'
270
270
  end
271
271
  end
@@ -273,7 +273,7 @@ describe Elasticity::EMR do
273
273
  context 'when a block is given' do
274
274
  let(:result) { '_' }
275
275
  it 'should yield the submission results' do
276
- Elasticity::AwsRequest.any_instance.should_receive(:submit).and_return(result)
276
+ Elasticity::AwsSession.any_instance.should_receive(:submit).and_return(result)
277
277
  subject.run_job_flow({}) do |xml|
278
278
  xml.should == '_'
279
279
  end
@@ -285,7 +285,7 @@ describe Elasticity::EMR do
285
285
  describe '#terminate_jobflows' do
286
286
 
287
287
  it 'should terminate the specific jobflow' do
288
- Elasticity::AwsRequest.any_instance.should_receive(:submit).with({
288
+ Elasticity::AwsSession.any_instance.should_receive(:submit).with({
289
289
  :operation => 'TerminateJobFlows',
290
290
  :job_flow_ids => ['j-1']
291
291
  })
@@ -295,7 +295,7 @@ describe Elasticity::EMR do
295
295
  context 'when a block is given' do
296
296
  let(:result) { '_' }
297
297
  it 'should yield the termination results' do
298
- Elasticity::AwsRequest.any_instance.should_receive(:submit).and_return(result)
298
+ Elasticity::AwsSession.any_instance.should_receive(:submit).and_return(result)
299
299
  subject.terminate_jobflows('j-1') do |xml|
300
300
  xml.should == '_'
301
301
  end
@@ -308,7 +308,7 @@ describe Elasticity::EMR do
308
308
 
309
309
  context 'when protection is enabled' do
310
310
  it 'should enable protection on the specified jobflows' do
311
- Elasticity::AwsRequest.any_instance.should_receive(:submit).with({
311
+ Elasticity::AwsSession.any_instance.should_receive(:submit).with({
312
312
  :operation => 'SetTerminationProtection',
313
313
  :termination_protected => true,
314
314
  :job_flow_ids => ['jobflow1', 'jobflow2']
@@ -319,7 +319,7 @@ describe Elasticity::EMR do
319
319
 
320
320
  context 'when protection is disabled' do
321
321
  it 'should disable protection on the specified jobflows' do
322
- Elasticity::AwsRequest.any_instance.should_receive(:submit).with({
322
+ Elasticity::AwsSession.any_instance.should_receive(:submit).with({
323
323
  :operation => 'SetTerminationProtection',
324
324
  :termination_protected => false,
325
325
  :job_flow_ids => ['jobflow1', 'jobflow2']
@@ -330,7 +330,7 @@ describe Elasticity::EMR do
330
330
 
331
331
  context 'when protection is not specified' do
332
332
  it 'should enable protection on the specified jobflows' do
333
- Elasticity::AwsRequest.any_instance.should_receive(:submit).with({
333
+ Elasticity::AwsSession.any_instance.should_receive(:submit).with({
334
334
  :operation => 'SetTerminationProtection',
335
335
  :termination_protected => true,
336
336
  :job_flow_ids => ['jobflow1', 'jobflow2']
@@ -342,7 +342,7 @@ describe Elasticity::EMR do
342
342
  context 'when a block is given' do
343
343
  let(:result) { '_' }
344
344
  it 'should yield the termination results' do
345
- Elasticity::AwsRequest.any_instance.should_receive(:submit).and_return(result)
345
+ Elasticity::AwsSession.any_instance.should_receive(:submit).and_return(result)
346
346
  subject.set_termination_protection([]) do |xml|
347
347
  xml.should == '_'
348
348
  end
@@ -355,7 +355,7 @@ describe Elasticity::EMR do
355
355
  let(:params) { {:foo => 'bar'} }
356
356
 
357
357
  it 'should pass through directly to the request and return the results of the request' do
358
- Elasticity::AwsRequest.any_instance.should_receive(:submit).with(params).and_return('RESULT')
358
+ Elasticity::AwsSession.any_instance.should_receive(:submit).with(params).and_return('RESULT')
359
359
  subject.direct(params).should == 'RESULT'
360
360
  end
361
361
  end