mortar 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. data/README.md +36 -0
  2. data/bin/mortar +13 -0
  3. data/lib/mortar.rb +23 -0
  4. data/lib/mortar/auth.rb +312 -0
  5. data/lib/mortar/cli.rb +54 -0
  6. data/lib/mortar/command.rb +267 -0
  7. data/lib/mortar/command/auth.rb +96 -0
  8. data/lib/mortar/command/base.rb +319 -0
  9. data/lib/mortar/command/clusters.rb +41 -0
  10. data/lib/mortar/command/describe.rb +97 -0
  11. data/lib/mortar/command/generate.rb +121 -0
  12. data/lib/mortar/command/help.rb +166 -0
  13. data/lib/mortar/command/illustrate.rb +97 -0
  14. data/lib/mortar/command/jobs.rb +174 -0
  15. data/lib/mortar/command/pigscripts.rb +45 -0
  16. data/lib/mortar/command/projects.rb +128 -0
  17. data/lib/mortar/command/validate.rb +94 -0
  18. data/lib/mortar/command/version.rb +42 -0
  19. data/lib/mortar/errors.rb +24 -0
  20. data/lib/mortar/generators/generator_base.rb +107 -0
  21. data/lib/mortar/generators/macro_generator.rb +37 -0
  22. data/lib/mortar/generators/pigscript_generator.rb +40 -0
  23. data/lib/mortar/generators/project_generator.rb +67 -0
  24. data/lib/mortar/generators/udf_generator.rb +28 -0
  25. data/lib/mortar/git.rb +233 -0
  26. data/lib/mortar/helpers.rb +488 -0
  27. data/lib/mortar/project.rb +156 -0
  28. data/lib/mortar/snapshot.rb +39 -0
  29. data/lib/mortar/templates/macro/macro.pig +14 -0
  30. data/lib/mortar/templates/pigscript/pigscript.pig +38 -0
  31. data/lib/mortar/templates/pigscript/python_udf.py +13 -0
  32. data/lib/mortar/templates/project/Gemfile +3 -0
  33. data/lib/mortar/templates/project/README.md +8 -0
  34. data/lib/mortar/templates/project/gitignore +4 -0
  35. data/lib/mortar/templates/project/macros/gitkeep +0 -0
  36. data/lib/mortar/templates/project/pigscripts/pigscript.pig +35 -0
  37. data/lib/mortar/templates/project/udfs/python/python_udf.py +13 -0
  38. data/lib/mortar/templates/udf/python_udf.py +13 -0
  39. data/lib/mortar/version.rb +20 -0
  40. data/lib/vendor/mortar/okjson.rb +598 -0
  41. data/lib/vendor/mortar/uuid.rb +312 -0
  42. data/spec/mortar/auth_spec.rb +156 -0
  43. data/spec/mortar/command/auth_spec.rb +46 -0
  44. data/spec/mortar/command/base_spec.rb +82 -0
  45. data/spec/mortar/command/clusters_spec.rb +61 -0
  46. data/spec/mortar/command/describe_spec.rb +135 -0
  47. data/spec/mortar/command/generate_spec.rb +139 -0
  48. data/spec/mortar/command/illustrate_spec.rb +140 -0
  49. data/spec/mortar/command/jobs_spec.rb +364 -0
  50. data/spec/mortar/command/pigscripts_spec.rb +70 -0
  51. data/spec/mortar/command/projects_spec.rb +165 -0
  52. data/spec/mortar/command/validate_spec.rb +119 -0
  53. data/spec/mortar/command_spec.rb +122 -0
  54. data/spec/mortar/git_spec.rb +278 -0
  55. data/spec/mortar/helpers_spec.rb +82 -0
  56. data/spec/mortar/project_spec.rb +76 -0
  57. data/spec/mortar/snapshot_spec.rb +46 -0
  58. data/spec/spec.opts +1 -0
  59. data/spec/spec_helper.rb +278 -0
  60. data/spec/support/display_message_matcher.rb +68 -0
  61. metadata +259 -0
@@ -0,0 +1,140 @@
1
+ #
2
+ # Copyright 2012 Mortar Data Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'spec_helper'
18
+ require 'fakefs/spec_helpers'
19
+ require 'mortar/command/illustrate'
20
+ require 'mortar/api/illustrate'
21
+ require 'launchy'
22
+
23
+ module Mortar::Command
24
+ describe Illustrate do
25
+
26
+ before(:each) do
27
+ stub_core
28
+ @git = Mortar::Git::Git.new
29
+ end
30
+
31
+ context("index") do
32
+
33
+ it "errors when an alias is not provided" do
34
+ with_git_initialized_project do |p|
35
+ write_file(File.join(p.pigscripts_path, "my_script.pig"))
36
+ stderr, stdout = execute("illustrate my_script", p)
37
+ stderr.should == <<-STDERR
38
+ ! Usage: mortar illustrate PIGSCRIPT ALIAS
39
+ ! Must specify PIGSCRIPT and ALIAS.
40
+ STDERR
41
+ end
42
+ end
43
+
44
+ it "errors when no remote exists in the project" do
45
+ with_git_initialized_project do |p|
46
+ @git.git('remote rm mortar')
47
+ p.remote = nil
48
+ write_file(File.join(p.pigscripts_path, "my_script.pig"))
49
+ stderr, stdout = execute("illustrate my_script my_alias", p, @git)
50
+ stderr.should == <<-STDERR
51
+ ! Unable to find git remote for project myproject
52
+ STDERR
53
+ end
54
+ end
55
+
56
+ it "errors when requested pigscript cannot be found" do
57
+ with_git_initialized_project do |p|
58
+ stderr, stdout = execute("illustrate does_not_exist my_alias", p, @git)
59
+ stderr.should == <<-STDERR
60
+ ! Unable to find pigscript does_not_exist
61
+ ! No pigscripts found
62
+ STDERR
63
+ end
64
+ end
65
+
66
+ it "requests and reports on a successful illustrate" do
67
+ with_git_initialized_project do |p|
68
+ # stub api requests
69
+ illustrate_id = "c571a8c7f76a4fd4a67c103d753e2dd5"
70
+ illustrate_url = "https://api.mortardata.com/illustrates/#{illustrate_id}"
71
+ parameters = ["name"=>"key", "value"=>"value" ]
72
+
73
+ # These don't test the validity of the error message, it only tests that the CLI can handle a message returned from the server
74
+ mock(Mortar::Auth.api).post_illustrate("myproject", "my_script", "my_alias", is_a(String), :parameters => parameters) {Excon::Response.new(:body => {"illustrate_id" => illustrate_id})}
75
+ mock(Mortar::Auth.api).get_illustrate(illustrate_id, :exclude_result => true).returns(Excon::Response.new(:body => {"status_code" => Mortar::API::Illustrate::STATUS_QUEUED, "status_description" => "Pending"})).ordered
76
+ mock(Mortar::Auth.api).get_illustrate(illustrate_id, :exclude_result => true).returns(Excon::Response.new(:body => {"status_code" => Mortar::API::Illustrate::STATUS_GATEWAY_STARTING, "status_description" => "GATEWAY_STARTING"})).ordered
77
+ mock(Mortar::Auth.api).get_illustrate(illustrate_id, :exclude_result => true).returns(Excon::Response.new(:body => {"status_code" => Mortar::API::Illustrate::STATUS_PROGRESS, "status_description" => "In progress"})).ordered
78
+ mock(Mortar::Auth.api).get_illustrate(illustrate_id, :exclude_result => true).returns(Excon::Response.new(:body => {"status_code" => Mortar::API::Illustrate::STATUS_READING_DATA, "status_description" => "Reading data"})).ordered
79
+ mock(Mortar::Auth.api).get_illustrate(illustrate_id, :exclude_result => true).returns(Excon::Response.new(:body => {"status_code" => Mortar::API::Illustrate::STATUS_PRUNING_DATA, "status_description" => "Pruning data"})).ordered
80
+ mock(Mortar::Auth.api).get_illustrate(illustrate_id, :exclude_result => true).returns(Excon::Response.new(:body => {"status_code" => Mortar::API::Illustrate::STATUS_SUCCESS, "status_description" => "Succeeded", "web_result_url" => illustrate_url})).ordered
81
+
82
+ # stub launchy
83
+ mock(Launchy).open(illustrate_url) {Thread.new {}}
84
+
85
+ write_file(File.join(p.pigscripts_path, "my_script.pig"))
86
+ stderr, stdout = execute("illustrate my_script my_alias --polling_interval 0.05 -p key=value", p, @git)
87
+ stdout.should == <<-STDOUT
88
+ Taking code snapshot... done
89
+ Sending code snapshot to Mortar... done
90
+ Starting illustrate... done
91
+
92
+ \r\e[0KStatus: Pending... /\r\e[0KStatus: GATEWAY_STARTING... -\r\e[0KStatus: In progress... \\\r\e[0KStatus: Reading data... |\r\e[0KStatus: Pruning data... /\r\e[0KStatus: Succeeded
93
+
94
+ Results available at https://api.mortardata.com/illustrates/c571a8c7f76a4fd4a67c103d753e2dd5
95
+ Opening web browser to show results... done
96
+ STDOUT
97
+ end
98
+ end
99
+
100
+ it "requests and reports on a failed illustrate" do
101
+ with_git_initialized_project do |p|
102
+ # stub api requests
103
+ illustrate_id = "c571a8c7f76a4fd4a67c103d753e2dd5"
104
+
105
+ error_message = "This is my error message\nWith multiple lines."
106
+ line_number = 23
107
+ column_number = 32
108
+ error_type = 'PigError'
109
+
110
+ # These don't test the validity of the error message, it only tests that the CLI can handle a message returned from the server
111
+ mock(Mortar::Auth.api).post_illustrate("myproject", "my_script", "my_alias", is_a(String), :parameters => []) {Excon::Response.new(:body => {"illustrate_id" => illustrate_id})}
112
+ mock(Mortar::Auth.api).get_illustrate(illustrate_id, :exclude_result => true).returns(Excon::Response.new(:body => {"status_code" => Mortar::API::Illustrate::STATUS_QUEUED, "status_description" => "Pending"})).ordered
113
+ mock(Mortar::Auth.api).get_illustrate(illustrate_id, :exclude_result => true).returns(Excon::Response.new(:body => {"status_code" => Mortar::API::Illustrate::STATUS_FAILURE,
114
+ "error_message" => error_message,
115
+ "line_number" => line_number,
116
+ "column_number" => column_number,
117
+ "error_type" => error_type,
118
+ "status_description" => "Failed"})).ordered
119
+
120
+ write_file(File.join(p.pigscripts_path, "my_script.pig"))
121
+ stderr, stdout = execute("illustrate my_script my_alias --polling_interval 0.05", p, @git)
122
+ stdout.should == <<-STDOUT
123
+ Taking code snapshot... done
124
+ Sending code snapshot to Mortar... done
125
+ Starting illustrate... done
126
+
127
+ \r\e[0KStatus: Pending... /\r\e[0KStatus: Failed
128
+
129
+ STDOUT
130
+ stderr.should == <<-STDERR
131
+ ! Illustrate failed with PigError at Line 23, Column 32:
132
+ !
133
+ ! This is my error message
134
+ ! With multiple lines.
135
+ STDERR
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,364 @@
1
+ #
2
+ # Copyright 2012 Mortar Data Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'spec_helper'
18
+ require 'fakefs/spec_helpers'
19
+ require 'mortar/command/jobs'
20
+ require 'mortar/api/jobs'
21
+
22
+ module Mortar::Command
23
+ describe Jobs do
24
+
25
+ before(:each) do
26
+ stub_core
27
+ @git = Mortar::Git::Git.new
28
+ end
29
+
30
+ context("index") do
31
+ end
32
+
33
+ context("run") do
34
+ it "handles singlejobcluster parameter" do
35
+ with_git_initialized_project do |p|
36
+ # stub api requests
37
+ job_id = "c571a8c7f76a4fd4a67c103d753e2dd5"
38
+ job_url = "http://127.0.0.1:5000/jobs/job_detail?job_id=c571a8c7f76a4fd4a67c103d753e2dd5"
39
+ cluster_size = 5
40
+
41
+ mock(Mortar::Auth.api).post_job_new_cluster("myproject", "my_script", is_a(String), cluster_size,
42
+ :parameters => match_array([{"name" => "FIRST_PARAM", "value" => "FOO"}, {"name" => "SECOND_PARAM", "value" => "BAR"}]),
43
+ :keepalive => false) {Excon::Response.new(:body => {"job_id" => job_id, "web_job_url" => job_url})}
44
+
45
+ write_file(File.join(p.pigscripts_path, "my_script.pig"))
46
+ stderr, stdout = execute("jobs:run my_script -1 --clustersize 5 -p FIRST_PARAM=FOO -p SECOND_PARAM=BAR", p, @git)
47
+ stdout.should == <<-STDOUT
48
+ Taking code snapshot... done
49
+ Sending code snapshot to Mortar... done
50
+ Requesting job execution... done
51
+ job_id: c571a8c7f76a4fd4a67c103d753e2dd5
52
+
53
+ Job status can be viewed on the web at:
54
+
55
+ http://127.0.0.1:5000/jobs/job_detail?job_id=c571a8c7f76a4fd4a67c103d753e2dd5
56
+
57
+ Or by running:
58
+
59
+ mortar jobs:status c571a8c7f76a4fd4a67c103d753e2dd5
60
+
61
+ STDOUT
62
+ end
63
+ end
64
+
65
+ it "runs a job on a new cluster" do
66
+ with_git_initialized_project do |p|
67
+ # stub api requests
68
+ job_id = "c571a8c7f76a4fd4a67c103d753e2dd5"
69
+ job_url = "http://127.0.0.1:5000/jobs/job_detail?job_id=c571a8c7f76a4fd4a67c103d753e2dd5"
70
+ cluster_size = 5
71
+
72
+ mock(Mortar::Auth.api).post_job_new_cluster("myproject", "my_script", is_a(String), cluster_size,
73
+ :parameters => match_array([{"name" => "FIRST_PARAM", "value" => "FOO"}, {"name" => "SECOND_PARAM", "value" => "BAR"}]),
74
+ :keepalive => true) {Excon::Response.new(:body => {"job_id" => job_id, "web_job_url" => job_url})}
75
+
76
+ write_file(File.join(p.pigscripts_path, "my_script.pig"))
77
+ stderr, stdout = execute("jobs:run my_script --clustersize 5 -p FIRST_PARAM=FOO -p SECOND_PARAM=BAR", p, @git)
78
+ stdout.should == <<-STDOUT
79
+ Taking code snapshot... done
80
+ Sending code snapshot to Mortar... done
81
+ Requesting job execution... done
82
+ job_id: c571a8c7f76a4fd4a67c103d753e2dd5
83
+
84
+ Job status can be viewed on the web at:
85
+
86
+ http://127.0.0.1:5000/jobs/job_detail?job_id=c571a8c7f76a4fd4a67c103d753e2dd5
87
+
88
+ Or by running:
89
+
90
+ mortar jobs:status c571a8c7f76a4fd4a67c103d753e2dd5
91
+
92
+ STDOUT
93
+ end
94
+ end
95
+
96
+ it "runs a job on an existing cluster" do
97
+ with_git_initialized_project do |p|
98
+ # stub api requests
99
+ job_id = "c571a8c7f76a4fd4a67c103d753e2dd5"
100
+ job_url = "http://127.0.0.1:5000/jobs/job_detail?job_id=c571a8c7f76a4fd4a67c103d753e2dd5"
101
+ cluster_id = "e2790e7e8c7d48e39157238d58191346"
102
+
103
+ mock(Mortar::Auth.api).post_job_existing_cluster("myproject", "my_script", is_a(String), cluster_id, :parameters => []) {Excon::Response.new(:body => {"job_id" => job_id, "web_job_url" => job_url})}
104
+
105
+ write_file(File.join(p.pigscripts_path, "my_script.pig"))
106
+ stderr, stdout = execute("jobs:run my_script --clusterid e2790e7e8c7d48e39157238d58191346", p, @git)
107
+ stdout.should == <<-STDOUT
108
+ Taking code snapshot... done
109
+ Sending code snapshot to Mortar... done
110
+ Requesting job execution... done
111
+ job_id: c571a8c7f76a4fd4a67c103d753e2dd5
112
+
113
+ Job status can be viewed on the web at:
114
+
115
+ http://127.0.0.1:5000/jobs/job_detail?job_id=c571a8c7f76a4fd4a67c103d753e2dd5
116
+
117
+ Or by running:
118
+
119
+ mortar jobs:status c571a8c7f76a4fd4a67c103d753e2dd5
120
+
121
+ STDOUT
122
+ end
123
+ end
124
+
125
+ it "runs a job with parameter file" do
126
+ with_git_initialized_project do |p|
127
+ job_id = "c571a8c7f76a4fd4a67c103d753e2dd5"
128
+ cluster_size = 5
129
+ keepalive = true
130
+
131
+ mock(Mortar::Auth.api).post_job_new_cluster("myproject", "my_script", is_a(String), cluster_size,
132
+ :parameters => match_array([{"name" => "FIRST", "value" => "FOO"}, {"name" => "SECOND", "value" => "BAR"}, {"name" => "THIRD", "value" => "BEAR\n"}]),
133
+ :keepalive => true) {Excon::Response.new(:body => {"job_id" => job_id})}
134
+
135
+ write_file(File.join(p.pigscripts_path, "my_script.pig"))
136
+
137
+ parameters = <<PARAMS
138
+ FIRST=PIZZA
139
+ SECOND=LASAGNA
140
+
141
+ THIRD=BEAR
142
+ PARAMS
143
+
144
+ write_file(File.join(p.root_path, "params.ini"), parameters)
145
+ stderr, stdout = execute("jobs:run my_script --clustersize 5 -p FIRST=FOO -p SECOND=BAR --param-file params.ini", p, @git)
146
+ end
147
+ end
148
+
149
+ it "runs a job with parameter file with comments" do
150
+ with_git_initialized_project do |p|
151
+ job_id = "c571a8c7f76a4fd4a67c103d753e2dd5"
152
+ cluster_size = 5
153
+ keepalive = true
154
+
155
+ mock(Mortar::Auth.api).post_job_new_cluster("myproject", "my_script", is_a(String), cluster_size,
156
+ :parameters => match_array([{"name" => "FIRST", "value" => "FOO"}, {"name" => "SECOND", "value" => "BAR"}, {"name" => "THIRD", "value" => "BEAR\n"}]),
157
+ :keepalive => true) {Excon::Response.new(:body => {"job_id" => job_id})}
158
+
159
+ write_file(File.join(p.pigscripts_path, "my_script.pig"))
160
+
161
+ parameters = <<PARAMS
162
+ FIRST=PIZZA
163
+ SECOND=LASAGNA
164
+ ; This is a test
165
+
166
+ THIRD=BEAR
167
+ PARAMS
168
+
169
+ write_file(File.join(p.root_path, "params.ini"), parameters)
170
+ stderr, stdout = execute("jobs:run my_script --clustersize 5 -p FIRST=FOO -p SECOND=BAR --param-file params.ini", p, @git)
171
+ end
172
+ end
173
+
174
+ it "runs a job with malformed parameter file" do
175
+ with_git_initialized_project do |p|
176
+ job_id = "c571a8c7f76a4fd4a67c103d753e2dd5"
177
+ cluster_size = 5
178
+ keepalive = true
179
+
180
+ write_file(File.join(p.pigscripts_path, "my_script.pig"))
181
+
182
+ parameters = <<PARAMS
183
+ FIRST=PIZZA
184
+ SECONDLASAGasNA
185
+ ; This is a test
186
+ Natta
187
+ THIRD=BEAR
188
+ PARAMS
189
+
190
+ write_file(File.join(p.root_path, "params.ini"), parameters)
191
+ stderr, stdout = execute("jobs:run my_script --clustersize 5 -p FIRST=FOO -p SECOND=BAR --param-file params.ini", p, @git)
192
+ stderr.should == <<-STDERR
193
+ ! Parameter file is malformed
194
+ STDERR
195
+ end
196
+ end
197
+ end
198
+
199
+ context("status") do
200
+
201
+ it "gets status for a completed, successful job" do
202
+ with_git_initialized_project do |p|
203
+ job_id = "c571a8c7f76a4fd4a67c103d753e2dd5"
204
+ pigscript_name = "my_script"
205
+ project_name = "myproject"
206
+ status_code = Mortar::API::Jobs::STATUS_SUCCESS
207
+ progress = 100
208
+ outputs = [{'name'=> 'hottest_songs_of_the_decade',
209
+ 'records' => 10,
210
+ 'alias' => 'output_data',
211
+ 'location' => 's3n://my-bucket/my-folder/hottest_songs_of_the_decade/output_data'},
212
+ {'name'=> 'hottest_songs_of_the_decade',
213
+ 'records' => 100,
214
+ 'alias' => 'output_data_2',
215
+ 'location' => 's3n://my-bucket/my-folder/hottest_songs_of_the_decade/output_data_2'}]
216
+ cluster_id = "e2790e7e8c7d48e39157238d58191346"
217
+ start_timestamp = "2012-02-28T03:35:42.831000+00:00"
218
+ running_timestamp = "2012-02-28T03:41:52.613000+00:00"
219
+ stop_timestamp = "2012-02-28T03:44:52.613000+00:00"
220
+ parameters = {"my_param_1" => "value1", "MY_PARAM_2" => "3"}
221
+
222
+ mock(Mortar::Auth.api).get_job(job_id) {Excon::Response.new(:body => {"job_id" => job_id,
223
+ "pigscript_name" => pigscript_name,
224
+ "project_name" => project_name,
225
+ "status_code" => status_code,
226
+ "status_description" => "Success",
227
+ "progress" => progress,
228
+ "cluster_id" => cluster_id,
229
+ "start_timestamp" => start_timestamp,
230
+ "running_timestamp" => running_timestamp,
231
+ "stop_timestamp" => stop_timestamp,
232
+ "duration" => "6 mins",
233
+ "num_hadoop_jobs" => 4,
234
+ "num_hadoop_jobs_succeeded" => 4,
235
+ "parameters" => parameters,
236
+ "outputs" => outputs
237
+ })}
238
+ stderr, stdout = execute("jobs:status c571a8c7f76a4fd4a67c103d753e2dd5", p, @git)
239
+ stdout.should == <<-STDOUT
240
+ === myproject: my_script (job_id: c571a8c7f76a4fd4a67c103d753e2dd5)
241
+ cluster_id: e2790e7e8c7d48e39157238d58191346
242
+ hadoop jobs complete: 4.00 / 4.00
243
+ job began running at: 2012-02-28T03:41:52.613000+00:00
244
+ job finished at: 2012-02-28T03:44:52.613000+00:00
245
+ job run with parameters:
246
+ MY_PARAM_2: 3
247
+ my_param_1: value1
248
+ job running for: 6 mins
249
+ job submitted at: 2012-02-28T03:35:42.831000+00:00
250
+ outputs:
251
+ output_data:
252
+ location: s3n://my-bucket/my-folder/hottest_songs_of_the_decade/output_data
253
+ records: 10
254
+ output_data_2:
255
+ location: s3n://my-bucket/my-folder/hottest_songs_of_the_decade/output_data_2
256
+ records: 100
257
+ progress: 100%
258
+ status: Success
259
+ STDOUT
260
+ end
261
+ end
262
+
263
+ it "gets status for a running job" do
264
+ with_git_initialized_project do |p|
265
+ job_id = "c571a8c7f76a4fd4a67c103d753e2dd5"
266
+ pigscript_name = "my_script"
267
+ project_name = "myproject"
268
+ status_code = Mortar::API::Jobs::STATUS_RUNNING
269
+ progress = 55
270
+ cluster_id = "e2790e7e8c7d48e39157238d58191346"
271
+ start_timestamp = "2012-02-28T03:35:42.831000+00:00"
272
+ running_timestamp = "2012-02-28T03:41:52.613000+00:00"
273
+ parameters = {"my_param_1" => "value1", "MY_PARAM_2" => "3"}
274
+
275
+ mock(Mortar::Auth.api).get_job(job_id) {Excon::Response.new(:body => {"job_id" => job_id,
276
+ "pigscript_name" => pigscript_name,
277
+ "project_name" => project_name,
278
+ "status_code" => status_code,
279
+ "status_description" => "Running",
280
+ "progress" => progress,
281
+ "cluster_id" => cluster_id,
282
+ "start_timestamp" => start_timestamp,
283
+ "running_timestamp" => running_timestamp,
284
+ "duration" => "6 mins",
285
+ "num_hadoop_jobs" => 4,
286
+ "num_hadoop_jobs_succeeded" => 2,
287
+ "parameters" => parameters
288
+ })}
289
+ stderr, stdout = execute("jobs:status c571a8c7f76a4fd4a67c103d753e2dd5", p, @git)
290
+ stdout.should == <<-STDOUT
291
+ === myproject: my_script (job_id: c571a8c7f76a4fd4a67c103d753e2dd5)
292
+ cluster_id: e2790e7e8c7d48e39157238d58191346
293
+ hadoop jobs complete: 2.00 / 4.00
294
+ job began running at: 2012-02-28T03:41:52.613000+00:00
295
+ job run with parameters:
296
+ MY_PARAM_2: 3
297
+ my_param_1: value1
298
+ job running for: 6 mins
299
+ job submitted at: 2012-02-28T03:35:42.831000+00:00
300
+ progress: 55%
301
+ status: Running
302
+ STDOUT
303
+ end
304
+ end
305
+
306
+ it "gets status for a error job" do
307
+ with_git_initialized_project do |p|
308
+ job_id = "c571a8c7f76a4fd4a67c103d753e2dd5"
309
+ pigscript_name = "my_script"
310
+ project_name = "myproject"
311
+ status_code = Mortar::API::Jobs::STATUS_EXECUTION_ERROR
312
+ progress = 55
313
+ cluster_id = "e2790e7e8c7d48e39157238d58191346"
314
+ start_timestamp = "2012-02-28T03:35:42.831000+00:00"
315
+ running_timestamp = "2012-02-28T03:41:52.613000+00:00"
316
+ stop_timestamp = "2012-02-28T03:45:52.613000+00:00"
317
+ parameters = {"my_param_1" => "value1", "MY_PARAM_2" => "3"}
318
+ error = {"message" => "An error occurred and here's some more info",
319
+ "type" => "RuntimeError",
320
+ "line_number" => 43,
321
+ "column_number" => 34}
322
+ mock(Mortar::Auth.api).get_job(job_id) {Excon::Response.new(:body => {"job_id" => job_id,
323
+ "pigscript_name" => pigscript_name,
324
+ "project_name" => project_name,
325
+ "status_code" => status_code,
326
+ "status_description" => "Execution error",
327
+ "progress" => progress,
328
+ "cluster_id" => cluster_id,
329
+ "start_timestamp" => start_timestamp,
330
+ "running_timestamp" => running_timestamp,
331
+ "stop_timestamp" => stop_timestamp,
332
+ "duration" => "6 mins",
333
+ "num_hadoop_jobs" => 4,
334
+ "num_hadoop_jobs_succeeded" => 0,
335
+ "parameters" => parameters,
336
+ "error" => error
337
+ })}
338
+ stderr, stdout = execute("jobs:status c571a8c7f76a4fd4a67c103d753e2dd5", p, @git)
339
+ stdout.should == <<-STDOUT
340
+ === myproject: my_script (job_id: c571a8c7f76a4fd4a67c103d753e2dd5)
341
+ cluster_id: e2790e7e8c7d48e39157238d58191346
342
+ error:
343
+ column_number: 34
344
+ line_number: 43
345
+ message: An error occurred and here's some more info
346
+ type: RuntimeError
347
+ hadoop jobs complete: 0.00 / 4.00
348
+ job began running at: 2012-02-28T03:41:52.613000+00:00
349
+ job finished at: 2012-02-28T03:45:52.613000+00:00
350
+ job run with parameters:
351
+ MY_PARAM_2: 3
352
+ my_param_1: value1
353
+ job running for: 6 mins
354
+ job submitted at: 2012-02-28T03:35:42.831000+00:00
355
+ progress: 55%
356
+ status: Execution error
357
+ STDOUT
358
+ end
359
+ end
360
+
361
+
362
+ end
363
+ end
364
+ end