mortar 0.15.26 → 0.15.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,117 @@
1
+ #
2
+ # Copyright 2014 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/luigi'
20
+ require 'mortar/api/jobs'
21
+
22
+ module Mortar::Command
23
+ describe Luigi do
24
+
25
+ before(:each) do
26
+ stub_core
27
+ @git = Mortar::Git::Git.new
28
+ end
29
+
30
+ context("index") do
31
+ it "shows help when user adds help argument" do
32
+ with_git_initialized_project do |p|
33
+ stderr_dash_h, stdout_dash_h = execute("luigi -h", p, @git)
34
+ stderr_help, stdout_help = execute("luigi help", p, @git)
35
+ stdout_dash_h.should == stdout_help
36
+ stderr_dash_h.should == stderr_help
37
+ end
38
+ end
39
+
40
+ it "runs a luigi job with no parameters" do
41
+ with_git_initialized_project do |p|
42
+ # stub api requests
43
+ job_id = "c571a8c7f76a4fd4a67c103d753e2dd5"
44
+ job_url = "http://127.0.0.1:5000/jobs/pipeline_job_detail?job_id=c571a8c7f76a4fd4a67c103d753e2dd5"
45
+ mock(Mortar::Auth.api).post_luigi_job("myproject", "my_script", is_a(String),
46
+ :project_script_path => be_a_kind_of(String),
47
+ :parameters => match_array([])
48
+ ) {Excon::Response.new(:body => {"job_id" => job_id, "web_job_url" => job_url})}
49
+
50
+ write_file(File.join(p.luigiscripts_path, "my_script.py"))
51
+ stderr, stdout = execute("luigi luigiscripts/my_script.py", p, @git)
52
+ stdout.should == <<-STDOUT
53
+ Taking code snapshot... done
54
+ Sending code snapshot to Mortar... done
55
+ Requesting job execution... done
56
+ job_id: c571a8c7f76a4fd4a67c103d753e2dd5
57
+
58
+ Job status can be viewed on the web at:
59
+
60
+ http://127.0.0.1:5000/jobs/pipeline_job_detail?job_id=c571a8c7f76a4fd4a67c103d753e2dd5
61
+
62
+ STDOUT
63
+ end
64
+ end
65
+
66
+ it "runs a luigi job with luigi-style parameters" do
67
+ with_git_initialized_project do |p|
68
+ # stub api requests
69
+ job_id = "c571a8c7f76a4fd4a67c103d753e2dd5"
70
+ job_url = "http://127.0.0.1:5000/jobs/pipeline_job_detail?job_id=c571a8c7f76a4fd4a67c103d753e2dd5"
71
+ mock(Mortar::Auth.api).post_luigi_job("myproject", "my_script", is_a(String),
72
+ :project_script_path => be_a_kind_of(String),
73
+ :parameters => match_array([{"name" => "my-luigi-parameter", "value" => "elephant"},
74
+ {"name" => "my-luigi-parameter-2", "value" => "14"}])
75
+ ) {Excon::Response.new(:body => {"job_id" => job_id, "web_job_url" => job_url})}
76
+
77
+ write_file(File.join(p.luigiscripts_path, "my_script.py"))
78
+ stderr, stdout = execute("luigi luigiscripts/my_script.py --my-luigi-parameter elephant --my-luigi-parameter-2 14", p, @git)
79
+ stdout.should == <<-STDOUT
80
+ Taking code snapshot... done
81
+ Sending code snapshot to Mortar... done
82
+ Requesting job execution... done
83
+ job_id: c571a8c7f76a4fd4a67c103d753e2dd5
84
+
85
+ Job status can be viewed on the web at:
86
+
87
+ http://127.0.0.1:5000/jobs/pipeline_job_detail?job_id=c571a8c7f76a4fd4a67c103d753e2dd5
88
+
89
+ STDOUT
90
+ end
91
+ end
92
+
93
+ it "errors when parameter does not have dash-dash at beginning of name" do
94
+ with_git_initialized_project do |p|
95
+ write_file(File.join(p.luigiscripts_path, "my_script.py"))
96
+ stderr, stdout = execute("luigi luigiscripts/my_script.py my-luigi-parameter-missing-dashdash", p, @git)
97
+ stdout.should == ""
98
+ stderr.should == <<-STDERR
99
+ ! Luigi parameter my-luigi-parameter-missing-dashdash must begin with --
100
+ STDERR
101
+ end
102
+ end
103
+
104
+ it "errors when no value provided for parameter" do
105
+ with_git_initialized_project do |p|
106
+ write_file(File.join(p.luigiscripts_path, "my_script.py"))
107
+ stderr, stdout = execute("luigi luigiscripts/my_script.py --p1 withvalue --p2", p, @git)
108
+ stdout.should == ""
109
+ stderr.should == <<-STDERR
110
+ ! No value provided for luigi parameter --p2
111
+ STDERR
112
+ end
113
+ end
114
+
115
+ end
116
+ end
117
+ end
@@ -152,10 +152,13 @@ STDOUT
152
152
  File.exists?("pigscripts/some_new_project.pig").should be_true
153
153
  File.exists?("udfs/python/some_new_project.py").should be_true
154
154
  File.exists?("luigiscripts/README").should be_true
155
+ File.exists?("luigiscripts/some_new_project_luigi.py").should be_true
156
+ File.exists?("luigiscripts/client.cfg.template").should be_true
155
157
  File.exists?("lib/README").should be_true
156
158
  File.exists?("params/README").should be_true
157
159
 
158
160
  File.read("pigscripts/some_new_project.pig").each_line { |line| line.match(/<%.*%>/).should be_nil }
161
+ File.read("luigiscripts/some_new_project_luigi.py").each_line { |line| line.match(/<%.*%>/).should be_nil }
159
162
 
160
163
  stdout.should == <<-STDOUT
161
164
  \r\e[0KVerifying GitHub username: /\r\e[0KVerifying GitHub username: -\r\e[0KVerifying GitHub username: Done!
@@ -180,6 +183,8 @@ Sending request to register project: some_new_project... done
180
183
  \e[1;32m create\e[0m udfs/java/.gitkeep
181
184
  \e[1;32m create\e[0m luigiscripts
182
185
  \e[1;32m create\e[0m luigiscripts/README
186
+ \e[1;32m create\e[0m luigiscripts/some_new_project_luigi.py
187
+ \e[1;32m create\e[0m luigiscripts/client.cfg.template
183
188
  \e[1;32m create\e[0m lib
184
189
  \e[1;32m create\e[0m lib/README
185
190
  \e[1;32m create\e[0m params
@@ -138,6 +138,111 @@ module Mortar
138
138
  end
139
139
  end
140
140
 
141
+ context "project manifest" do
142
+ it "adds luigiscripts if the directory exists and manifest does not have it" do
143
+ with_git_initialized_project do |p|
144
+ # ensure luigiscripts path exists
145
+ luigiscripts_path = File.join(p.root_path, "luigiscripts")
146
+ unless File.directory? luigiscripts_path
147
+ FileUtils.mkdir_p(luigiscripts_path)
148
+ end
149
+
150
+ # remove it from manifest
151
+ manifest_without_luigiscripts = <<-MANIFEST0
152
+ lib
153
+ macros
154
+ pigscripts
155
+ udfs
156
+ MANIFEST0
157
+ manifest_path = File.join(p.root_path, "project.manifest")
158
+ write_file(manifest_path, manifest_without_luigiscripts)
159
+
160
+ project_manifest_before = File.open(manifest_path, "r").read
161
+ project_manifest_before.include?("luigiscripts").should be_false
162
+
163
+ @git.ensure_luigiscripts_in_project_manifest()
164
+
165
+ project_manifest_after = File.open(manifest_path, "r").read
166
+ project_manifest_after.should == <<-MANIFEST0AFTER
167
+ lib
168
+ macros
169
+ pigscripts
170
+ udfs
171
+ luigiscripts
172
+ MANIFEST0AFTER
173
+ end
174
+ end
175
+
176
+ it "does not add luigiscripts if the directory does not exist" do
177
+ with_git_initialized_project do |p|
178
+ # ensure luigiscripts path does not exist
179
+ luigiscripts_path = File.join(p.root_path, "luigiscripts")
180
+ if File.directory? luigiscripts_path
181
+ FileUtils.rm_rf(luigiscripts_path)
182
+ end
183
+
184
+ # remove it from manifest
185
+ manifest_without_luigiscripts = <<-MANIFEST1
186
+ lib
187
+ macros
188
+ pigscripts
189
+ udfs
190
+ MANIFEST1
191
+ manifest_path = File.join(p.root_path, "project.manifest")
192
+ write_file(manifest_path, manifest_without_luigiscripts)
193
+
194
+ project_manifest_before = File.open(manifest_path, "r").read
195
+ project_manifest_before.include?("luigiscripts").should be_false
196
+
197
+ @git.ensure_luigiscripts_in_project_manifest()
198
+
199
+ project_manifest_after = File.open(manifest_path, "r").read
200
+ project_manifest_after.should == <<-MANIFEST1AFTER
201
+ lib
202
+ macros
203
+ pigscripts
204
+ udfs
205
+ MANIFEST1AFTER
206
+ end
207
+ end
208
+
209
+ it "handles manifest with no trailing newline" do
210
+ with_git_initialized_project do |p|
211
+ # ensure luigiscripts path exists
212
+ luigiscripts_path = File.join(p.root_path, "luigiscripts")
213
+ unless File.directory? luigiscripts_path
214
+ FileUtils.mkdir_p(luigiscripts_path)
215
+ end
216
+
217
+ # remove it from manifest
218
+ manifest_without_luigiscripts = <<-MANIFEST2
219
+ lib
220
+ macros
221
+ pigscripts
222
+ udfs
223
+ MANIFEST2
224
+ # strip the trailing newline
225
+ manifest_without_luigiscripts.strip!
226
+ manifest_path = File.join(p.root_path, "project.manifest")
227
+ write_file(manifest_path, manifest_without_luigiscripts)
228
+
229
+ project_manifest_before = File.open(manifest_path, "r").read
230
+ project_manifest_before.include?("luigiscripts").should be_false
231
+
232
+ @git.ensure_luigiscripts_in_project_manifest()
233
+
234
+ project_manifest_after = File.open(manifest_path, "r").read
235
+ project_manifest_after.should == <<-MANIFEST2AFTER
236
+ lib
237
+ macros
238
+ pigscripts
239
+ udfs
240
+ luigiscripts
241
+ MANIFEST2AFTER
242
+ end
243
+ end
244
+ end
245
+
141
246
  context "stash" do
142
247
  context "did_stash_changes" do
143
248
  it "finds that no changes were stashed" do
@@ -113,6 +113,12 @@ module Mortar::Local
113
113
  expect(@installutil.is_newer_version('foo', 'http://bar')).to be_true
114
114
  end
115
115
 
116
+ it "is if remote file last-modfied is unavailable" do
117
+ stub(@installutil).install_date.returns(1)
118
+ stub(@installutil).url_date.returns(nil)
119
+ expect(@installutil.is_newer_version('foo', 'http://bar')).to be_false
120
+ end
121
+
116
122
  it "is not if remote file is older" do
117
123
  stub(@installutil).install_date.returns(2)
118
124
  stub(@installutil).url_date.returns(1)
@@ -0,0 +1,101 @@
1
+ #
2
+ # Copyright 2014 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 'mortar/local/params'
19
+
20
+ module Mortar::Local
21
+ describe Params do
22
+
23
+ class ParamsClass
24
+ # this is usually mixed in from InstallUtil
25
+ def project_root
26
+ "/tmp/myproject"
27
+ end
28
+ end
29
+
30
+ before(:each) do
31
+ @params = ParamsClass.new
32
+ @params.extend(Mortar::Local::Params)
33
+ end
34
+
35
+ context "automatic_parameters" do
36
+
37
+ def get_param_value(params, name)
38
+ selected = params.select{|p| p["name"] == name}
39
+ selected.length == 1 ? selected[0]["value"] : nil
40
+ end
41
+
42
+ it "returns params for a logged-in user" do
43
+ ENV['AWS_ACCESS_KEY'] = "abc"
44
+ ENV['AWS_SECRET_KEY'] = "012"
45
+
46
+ # setup fake auth
47
+ stub_core
48
+ params = @params.automatic_parameters()
49
+ get_param_value(params, "MORTAR_EMAIL").should == "email@example.com"
50
+ get_param_value(params, "MORTAR_API_KEY").should == "pass"
51
+ get_param_value(params, "MORTAR_EMAIL_S3_ESCAPED").should == "email-example-com"
52
+ get_param_value(params, "MORTAR_PROJECT_ROOT").should == "/tmp/myproject"
53
+ get_param_value(params, "AWS_ACCESS_KEY").should == "abc"
54
+ get_param_value(params, "AWS_ACCESS_KEY_ID").should == "abc"
55
+ get_param_value(params, "aws_access_key_id").should == "abc"
56
+ get_param_value(params, "AWS_SECRET_KEY").should == "012"
57
+ get_param_value(params, "AWS_SECRET_ACCESS_KEY").should == "012"
58
+ get_param_value(params, "aws_secret_access_key").should == "012"
59
+ end
60
+
61
+ it "returns params for a non-logged-in user" do
62
+ ENV['AWS_ACCESS_KEY'] = "abc"
63
+ ENV['AWS_SECRET_KEY'] = "012"
64
+
65
+ params = @params.automatic_parameters()
66
+ get_param_value(params, "MORTAR_EMAIL").should == "notloggedin@user.org"
67
+ get_param_value(params, "MORTAR_API_KEY").should == "notloggedin"
68
+ get_param_value(params, "MORTAR_EMAIL_S3_ESCAPED").should == "notloggedin-user-org"
69
+ get_param_value(params, "MORTAR_PROJECT_ROOT").should == "/tmp/myproject"
70
+ get_param_value(params, "AWS_ACCESS_KEY").should == "abc"
71
+ get_param_value(params, "AWS_ACCESS_KEY_ID").should == "abc"
72
+ get_param_value(params, "aws_access_key_id").should == "abc"
73
+ get_param_value(params, "AWS_SECRET_KEY").should == "012"
74
+ get_param_value(params, "AWS_SECRET_ACCESS_KEY").should == "012"
75
+ get_param_value(params, "aws_secret_access_key").should == "012"
76
+ end
77
+ end
78
+
79
+ context "merge_parameters" do
80
+ it "merges parameters" do
81
+ @params.merge_parameters([], []).should == []
82
+ @params.merge_parameters(
83
+ [{"name" => "foo", "value" => "bar"}],
84
+ []).should ==
85
+ [{"name" => "foo", "value" => "bar"}]
86
+ @params.merge_parameters(
87
+ [],
88
+ [{"name" => "foo", "value" => "bar"}]).should ==
89
+ [{"name" => "foo", "value" => "bar"}]
90
+ @params.merge_parameters(
91
+ [{"name" => "foo", "value" => "bar"}],
92
+ [{"name" => "foo", "value" => "fish"}]).should ==
93
+ [{"name" => "foo", "value" => "fish"}]
94
+ @params.merge_parameters(
95
+ [{"name" => "tree", "value" => "bar"}],
96
+ [{"name" => "foo", "value" => "fish"}]).should ==
97
+ [{"name" => "foo", "value" => "fish"}, {"name" => "tree", "value" => "bar"}]
98
+ end
99
+ end
100
+ end
101
+ end
@@ -111,7 +111,7 @@ MESSAGE
111
111
  LoadedInit.should be_true
112
112
  end
113
113
 
114
- describe "installing plugins with dependencies" do
114
+ describe "installing plugins with dependencies", :broken => true do
115
115
  it "should install plugin dependencies" do
116
116
  ## Setup Fake Gem
117
117
  mortar_fake_gem_folder = create_fake_gem("/tmp")
data/spec/spec_helper.rb CHANGED
@@ -180,6 +180,7 @@ def with_blank_project_with_name(name, &block)
180
180
  FileUtils.mkdir_p(project_path)
181
181
 
182
182
  # setup project subdirectories
183
+ FileUtils.mkdir_p(File.join(project_path, "luigiscripts"))
183
184
  FileUtils.mkdir_p(File.join(project_path, "pigscripts"))
184
185
  FileUtils.mkdir_p(File.join(project_path, "macros"))
185
186
  FileUtils.mkdir_p(File.join(project_path, "udfs"))
@@ -392,6 +393,7 @@ end
392
393
  RSpec.configure do |config|
393
394
  config.mock_with :rr
394
395
  config.color_enabled = true
396
+ config.filter_run_excluding :broken => true
395
397
  config.include DisplayMessageMatcher
396
398
  config.before { Mortar::Helpers.error_with_failure = false }
397
399
  config.after { RR.verify; RR.reset }
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mortar
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 21
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 15
9
- - 26
10
- version: 0.15.26
9
+ - 27
10
+ version: 0.15.27
11
11
  platform: ruby
12
12
  authors:
13
13
  - Mortar Data
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2014-09-30 00:00:00 Z
18
+ date: 2014-10-06 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: rdoc
@@ -41,12 +41,12 @@ dependencies:
41
41
  requirements:
42
42
  - - ~>
43
43
  - !ruby/object:Gem::Version
44
- hash: 49
44
+ hash: 47
45
45
  segments:
46
46
  - 0
47
47
  - 8
48
- - 7
49
- version: 0.8.7
48
+ - 8
49
+ version: 0.8.8
50
50
  type: :runtime
51
51
  version_requirements: *id002
52
52
  - !ruby/object:Gem::Dependency
@@ -249,6 +249,7 @@ files:
249
249
  - lib/mortar/command/illustrate.rb
250
250
  - lib/mortar/command/jobs.rb
251
251
  - lib/mortar/command/local.rb
252
+ - lib/mortar/command/luigi.rb
252
253
  - lib/mortar/command/pigscripts.rb
253
254
  - lib/mortar/command/plugins.rb
254
255
  - lib/mortar/command/projects.rb
@@ -270,6 +271,7 @@ files:
270
271
  - lib/mortar/local/installutil.rb
271
272
  - lib/mortar/local/java.rb
272
273
  - lib/mortar/local/jython.rb
274
+ - lib/mortar/local/params.rb
273
275
  - lib/mortar/local/pig.rb
274
276
  - lib/mortar/local/python.rb
275
277
  - lib/mortar/local/sqoop.rb
@@ -304,6 +306,8 @@ files:
304
306
  - lib/mortar/templates/project/gitignore
305
307
  - lib/mortar/templates/project/lib/README
306
308
  - lib/mortar/templates/project/luigiscripts/README
309
+ - lib/mortar/templates/project/luigiscripts/client.cfg.template
310
+ - lib/mortar/templates/project/luigiscripts/luigiscript.py
307
311
  - lib/mortar/templates/project/macros/gitkeep
308
312
  - lib/mortar/templates/project/params/README
309
313
  - lib/mortar/templates/project/pigscripts/pigscript.pig
@@ -322,6 +326,7 @@ files:
322
326
  - lib/mortar/templates/report/illustrate-report.html
323
327
  - lib/mortar/templates/script/runpig.sh
324
328
  - lib/mortar/templates/script/runpython.sh
329
+ - lib/mortar/templates/script/runstillson.sh
325
330
  - lib/mortar/templates/script/sqoop.sh
326
331
  - lib/mortar/templates/udf/python_udf.py
327
332
  - lib/mortar/updater.rb
@@ -338,6 +343,7 @@ files:
338
343
  - spec/mortar/command/illustrate_spec.rb
339
344
  - spec/mortar/command/jobs_spec.rb
340
345
  - spec/mortar/command/local_spec.rb
346
+ - spec/mortar/command/luigi_spec.rb
341
347
  - spec/mortar/command/pigscripts_spec.rb
342
348
  - spec/mortar/command/projects_spec.rb
343
349
  - spec/mortar/command/s3_spec.rb
@@ -350,6 +356,7 @@ files:
350
356
  - spec/mortar/local/installutil_spec.rb
351
357
  - spec/mortar/local/java_spec.rb
352
358
  - spec/mortar/local/jython_spec.rb
359
+ - spec/mortar/local/params_spec.rb
353
360
  - spec/mortar/local/pig_spec.rb
354
361
  - spec/mortar/local/python_spec.rb
355
362
  - spec/mortar/local/sqoop_spec.rb