mortar 0.15.26 → 0.15.27
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/mortar/auth.rb +13 -5
- data/lib/mortar/command/base.rb +20 -0
- data/lib/mortar/command/help.rb +1 -1
- data/lib/mortar/command/jobs.rb +2 -2
- data/lib/mortar/command/local.rb +21 -8
- data/lib/mortar/command/luigi.rb +86 -0
- data/lib/mortar/generators/project_generator.rb +2 -0
- data/lib/mortar/git.rb +30 -0
- data/lib/mortar/local/controller.rb +6 -2
- data/lib/mortar/local/installutil.rb +9 -1
- data/lib/mortar/local/params.rb +68 -0
- data/lib/mortar/local/pig.rb +8 -29
- data/lib/mortar/local/python.rb +21 -2
- data/lib/mortar/templates/project/gitignore +1 -0
- data/lib/mortar/templates/project/luigiscripts/client.cfg.template +33 -0
- data/lib/mortar/templates/project/luigiscripts/luigiscript.py +134 -0
- data/lib/mortar/templates/project/project.manifest +1 -0
- data/lib/mortar/templates/script/runstillson.sh +25 -0
- data/lib/mortar/version.rb +1 -1
- data/spec/mortar/auth_spec.rb +8 -0
- data/spec/mortar/command/generate_spec.rb +1 -0
- data/spec/mortar/command/jobs_spec.rb +13 -13
- data/spec/mortar/command/local_spec.rb +41 -3
- data/spec/mortar/command/luigi_spec.rb +117 -0
- data/spec/mortar/command/projects_spec.rb +5 -0
- data/spec/mortar/git_spec.rb +105 -0
- data/spec/mortar/local/installutil_spec.rb +6 -0
- data/spec/mortar/local/params_spec.rb +101 -0
- data/spec/mortar/plugin_spec.rb +1 -1
- data/spec/spec_helper.rb +2 -0
- metadata +14 -7
data/lib/mortar/local/python.rb
CHANGED
@@ -15,15 +15,17 @@
|
|
15
15
|
#
|
16
16
|
|
17
17
|
require "mortar/local/installutil"
|
18
|
+
require "mortar/local/params"
|
18
19
|
|
19
20
|
class Mortar::Local::Python
|
20
21
|
include Mortar::Local::InstallUtil
|
22
|
+
include Mortar::Local::Params
|
21
23
|
|
22
24
|
PYTHON_OSX_TGZ_NAME = "mortar-python-osx.tgz"
|
23
25
|
PYTHON_OSX_TGZ_DEFAULT_URL_PATH = "resource/python_osx"
|
24
26
|
PYPI_URL_PATH = "resource/mortar_pypi"
|
25
27
|
|
26
|
-
MORTAR_PYTHON_PACKAGES = ["luigi", "mortar-luigi"]
|
28
|
+
MORTAR_PYTHON_PACKAGES = ["luigi", "mortar-luigi", "stillson"]
|
27
29
|
|
28
30
|
# Path to the python binary that should be used
|
29
31
|
# for running UDFs
|
@@ -318,7 +320,19 @@ class Mortar::Local::Python
|
|
318
320
|
|
319
321
|
def run_luigi_script(luigi_script, user_script_args)
|
320
322
|
template_params = luigi_command_template_parameters(luigi_script, user_script_args)
|
321
|
-
|
323
|
+
run_templated_script(python_command_script_template_path, template_params)
|
324
|
+
end
|
325
|
+
|
326
|
+
def run_stillson_luigi_client_cfg_expansion(luigi_script, project_config_parameters)
|
327
|
+
# combine automatic mortar parameters with
|
328
|
+
# parameters provided in the project config
|
329
|
+
auto_params = automatic_parameters()
|
330
|
+
parameters = merge_parameters(auto_params, project_config_parameters)
|
331
|
+
stillson_template_params = {
|
332
|
+
:parameters => parameters,
|
333
|
+
:luigi_script => luigi_script.executable_path()
|
334
|
+
}
|
335
|
+
run_templated_script(stillson_command_script_template_path, stillson_template_params)
|
322
336
|
end
|
323
337
|
|
324
338
|
# Path to the template which generates the bash script for running python
|
@@ -326,6 +340,11 @@ class Mortar::Local::Python
|
|
326
340
|
File.expand_path("../../templates/script/runpython.sh", __FILE__)
|
327
341
|
end
|
328
342
|
|
343
|
+
# Path to the template which generates the bash script for running stillson
|
344
|
+
def stillson_command_script_template_path
|
345
|
+
File.expand_path("../../templates/script/runstillson.sh", __FILE__)
|
346
|
+
end
|
347
|
+
|
329
348
|
def luigi_logging_config_file_path
|
330
349
|
File.expand_path("../../conf/luigi/logging.ini", __FILE__)
|
331
350
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
#
|
2
|
+
# This is the configuration file your Luigi pipelines.
|
3
|
+
#
|
4
|
+
# When you run "mortar local:luigi" or "mortar luigi", Mortar will expand
|
5
|
+
# the variables in this file (e.g. MORTAR_EMAIL) to their actual values
|
6
|
+
# and store the result in "luigiscripts/client.cfg". You should not check
|
7
|
+
# "luigiscripts/client.cfg" into source control, as it will be generated
|
8
|
+
# on each new run.
|
9
|
+
#
|
10
|
+
# In this file, you can reference any internal Mortar configuration variables
|
11
|
+
# (e.g. MORTAR_EMAIL, AWS_ACCESS_KEY_ID), or any
|
12
|
+
# project configuration variables you've set with "mortar config:set".
|
13
|
+
#
|
14
|
+
# Read more at https://help.mortardata.com/technologies/luigi/luigi_configuration
|
15
|
+
#
|
16
|
+
|
17
|
+
|
18
|
+
#
|
19
|
+
# Mortar credentials to run jobs and query for
|
20
|
+
# state from the Mortar API.
|
21
|
+
#
|
22
|
+
[mortar]
|
23
|
+
email: ${MORTAR_EMAIL}
|
24
|
+
api_key: ${MORTAR_API_KEY}
|
25
|
+
host: api.mortardata.com
|
26
|
+
|
27
|
+
#
|
28
|
+
# AWS credentials to check for completed output
|
29
|
+
# and store job completion tokens in S3 from Luigi.
|
30
|
+
#
|
31
|
+
[s3]
|
32
|
+
aws_access_key_id: ${AWS_ACCESS_KEY_ID}
|
33
|
+
aws_secret_access_key: ${AWS_SECRET_ACCESS_KEY}
|
@@ -0,0 +1,134 @@
|
|
1
|
+
import luigi
|
2
|
+
from luigi import configuration
|
3
|
+
from luigi.s3 import S3Target, S3PathTask
|
4
|
+
|
5
|
+
from mortar.luigi import mortartask
|
6
|
+
|
7
|
+
"""
|
8
|
+
Luigi is a powerful, easy-to-use framework for building data pipelines.
|
9
|
+
|
10
|
+
This is an example Luigi script to get you started. This script has a
|
11
|
+
'fill in the blank' interaction. Feel free to alter it to build your pipeline.
|
12
|
+
|
13
|
+
In this example we will run a Pig script, and then shutdown any clusters associated
|
14
|
+
with that script. We will do that by running the ShutdownClusters Task,
|
15
|
+
which is dependent on RunMyExamplePigScript Task. This means the cluster will only
|
16
|
+
shutdown after RunMyExamplePigScript (where the data transformation happens)
|
17
|
+
Task is completed.
|
18
|
+
|
19
|
+
For full tutorials and in-depth Luigi documentation, visit:
|
20
|
+
https://help.mortardata.com/technologies/luigi
|
21
|
+
|
22
|
+
To Run:
|
23
|
+
mortar luigi luigiscripts/<%= project_name_alias %>_luigi.py \
|
24
|
+
--output-base-path "s3://mortar-example-output-data/<your_username_here>/<%= project_name_alias %>"
|
25
|
+
"""
|
26
|
+
|
27
|
+
MORTAR_PROJECT = '<%= project_name_alias %>'
|
28
|
+
|
29
|
+
# helper function
|
30
|
+
def create_full_path(base_path, sub_path):
|
31
|
+
return '%s/%s' % (base_path, sub_path)
|
32
|
+
|
33
|
+
class RunMyExamplePigScript(mortartask.MortarProjectPigscriptTask):
|
34
|
+
"""
|
35
|
+
This is a Luigi Task that extends MortarProjectPigscriptTask to run a Pig
|
36
|
+
script on Mortar.
|
37
|
+
"""
|
38
|
+
|
39
|
+
"""
|
40
|
+
The location in S3 where the output of the Mortar job will be written.
|
41
|
+
"""
|
42
|
+
output_base_path = luigi.Parameter()
|
43
|
+
|
44
|
+
"""
|
45
|
+
Default cluster size to use for running Mortar jobs. A cluster size of 0
|
46
|
+
will run in Mortar's local mode. This is a fast (and free!) way to run jobs
|
47
|
+
on small data samples. Cluster sizes >= 2 will run on a Hadoop cluster.
|
48
|
+
"""
|
49
|
+
cluster_size = luigi.IntParameter(default=0)
|
50
|
+
|
51
|
+
"""
|
52
|
+
Path to input data being analyzed using the Pig script.
|
53
|
+
"""
|
54
|
+
input_path = luigi.Parameter(default ='s3://mortar-example-data/tutorial/excite.log.bz2')
|
55
|
+
|
56
|
+
|
57
|
+
def requires(self):
|
58
|
+
"""
|
59
|
+
The requires method specifies a list of other Tasks that must be complete
|
60
|
+
for this Task to run. In this case, we want to require that our input
|
61
|
+
exists on S3 before we run the script. S3PathTask validates that the
|
62
|
+
specified file or directory exists on S3.
|
63
|
+
"""
|
64
|
+
return [S3PathTask(self.input_path)]
|
65
|
+
|
66
|
+
def project(self):
|
67
|
+
"""
|
68
|
+
Name of Mortar Project to run.
|
69
|
+
"""
|
70
|
+
return MORTAR_PROJECT
|
71
|
+
|
72
|
+
def script_output(self):
|
73
|
+
"""
|
74
|
+
The script_output method is how you define where the output from this task
|
75
|
+
will be stored. Luigi will check this output location before starting any
|
76
|
+
tasks that depend on this task.
|
77
|
+
"""
|
78
|
+
return[S3Target(self.output_base_path + '/pigoutput')]
|
79
|
+
|
80
|
+
def token_path(self):
|
81
|
+
"""
|
82
|
+
Luigi manages dependencies between tasks by checking for the existence of
|
83
|
+
files. When one task finishes it writes out a 'token' file that will
|
84
|
+
trigger the next task in the dependency graph. This is the base path for
|
85
|
+
where those tokens will be written.
|
86
|
+
"""
|
87
|
+
return self.output_base_path
|
88
|
+
|
89
|
+
def parameters(self):
|
90
|
+
"""
|
91
|
+
Parameters for this pig job.
|
92
|
+
"""
|
93
|
+
return {'INPUT_PATH': self.input_path,
|
94
|
+
'OUTPUT_PATH': self.output_base_path + '/pigoutput'}
|
95
|
+
|
96
|
+
def script(self):
|
97
|
+
"""
|
98
|
+
Name of Pig script to run.
|
99
|
+
"""
|
100
|
+
return '<%= project_name_alias %>'
|
101
|
+
|
102
|
+
|
103
|
+
class ShutdownClusters(mortartask.MortarClusterShutdownTask):
|
104
|
+
"""
|
105
|
+
When the pipeline is completed, this task shuts down all active clusters not
|
106
|
+
currently running jobs. As this task is only shutting down clusters and not
|
107
|
+
generating any output data, this S3 location is used to store a 'token' file
|
108
|
+
indicating when the task has been completed.
|
109
|
+
"""
|
110
|
+
output_base_path = luigi.Parameter()
|
111
|
+
|
112
|
+
def requires(self):
|
113
|
+
"""
|
114
|
+
The ShutdownClusters task is dependent on RunMyExamplePigScript because a
|
115
|
+
cluster should not shut down until all the tasks are completed. You can
|
116
|
+
think of this as saying 'shut down my cluster after running my task'.
|
117
|
+
"""
|
118
|
+
return RunMyExamplePigScript(output_base_path = self.output_base_path)
|
119
|
+
|
120
|
+
def output(self):
|
121
|
+
"""
|
122
|
+
This output statement is needed because ShutdownClusters has no actual
|
123
|
+
output. We write a token with the class name to S3 to know that this task
|
124
|
+
has completed and it does not need to be run again.
|
125
|
+
"""
|
126
|
+
return [S3Target((create_full_path(self.output_base_path, 'ShutdownClusters')))]
|
127
|
+
|
128
|
+
if __name__ == "__main__":
|
129
|
+
"""
|
130
|
+
The final task in your pipeline, which will in turn pull in any dependencies
|
131
|
+
need to be run should be called in the main method. In this case ShutdownClusters
|
132
|
+
is being called.
|
133
|
+
"""
|
134
|
+
luigi.run(main_task_cls= ShutdownClusters)
|
@@ -0,0 +1,25 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
set -e
|
4
|
+
|
5
|
+
# Setup python environment
|
6
|
+
source <%= @local_install_dir %>/pythonenv/bin/activate
|
7
|
+
|
8
|
+
# template config file
|
9
|
+
export LUIGI_CONFIG_TEMPLATE_PATH=`pwd`/`dirname <%= @luigi_script %>`/client.cfg.template
|
10
|
+
|
11
|
+
# expanded config file
|
12
|
+
export LUIGI_CONFIG_PATH=`pwd`/`dirname <%= @luigi_script %>`/client.cfg
|
13
|
+
|
14
|
+
# Setup parameters in environment variables
|
15
|
+
<% @parameters.each do |p| %>
|
16
|
+
export <%= p['name'] %>="<%= p['value'] %>";
|
17
|
+
<% end %>
|
18
|
+
|
19
|
+
# Run stillson to expand the configuration template
|
20
|
+
if [ -f "$LUIGI_CONFIG_TEMPLATE_PATH" ]
|
21
|
+
then
|
22
|
+
stillson "$LUIGI_CONFIG_TEMPLATE_PATH" -o $LUIGI_CONFIG_PATH
|
23
|
+
else
|
24
|
+
echo "No luigi client configuration template found in expected location $LUIGI_CONFIG_TEMPLATE_PATH. Not expanding."
|
25
|
+
fi
|
data/lib/mortar/version.rb
CHANGED
data/spec/mortar/auth_spec.rb
CHANGED
@@ -182,5 +182,13 @@ module Mortar
|
|
182
182
|
end
|
183
183
|
end
|
184
184
|
|
185
|
+
it "does not prompt for username in local mode if user not logged in" do
|
186
|
+
@cli.user(true).should == 'notloggedin@user.org'
|
187
|
+
@cli.user_s3_safe(true).should == 'notloggedin-user-org'
|
188
|
+
end
|
189
|
+
|
190
|
+
it "does not prompt for password in local mode if user not logged in" do
|
191
|
+
@cli.password(true).should == 'notloggedin'
|
192
|
+
end
|
185
193
|
end
|
186
194
|
end
|
@@ -39,6 +39,7 @@ describe Mortar::Command::Generate do
|
|
39
39
|
File.exists?("Test/macros/.gitkeep").should be_true
|
40
40
|
File.exists?("Test/pigscripts/Test.pig").should be_true
|
41
41
|
File.exists?("Test/udfs/python/Test.py").should be_true
|
42
|
+
File.exists?("Test/luigiscripts/README").should be_true
|
42
43
|
|
43
44
|
File.read("Test/pigscripts/Test.pig").each_line { |line| line.match(/<%.*%>/).should be_nil }
|
44
45
|
end
|
@@ -46,7 +46,7 @@ module Mortar::Command
|
|
46
46
|
job_url = "http://127.0.0.1:5000/jobs/job_detail?job_id=c571a8c7f76a4fd4a67c103d753e2dd5"
|
47
47
|
cluster_size = 5
|
48
48
|
|
49
|
-
mock(Mortar::Auth.api).
|
49
|
+
mock(Mortar::Auth.api).post_pig_job_new_cluster("myproject", "my_script", is_a(String), cluster_size,
|
50
50
|
:pig_version => "0.9",
|
51
51
|
:project_script_path => be_a_kind_of(String),
|
52
52
|
:parameters => match_array([{"name" => "FIRST_PARAM", "value" => "FOO"}, {"name" => "SECOND_PARAM", "value" => "BAR"}]),
|
@@ -82,7 +82,7 @@ STDOUT
|
|
82
82
|
job_url = "http://127.0.0.1:5000/jobs/job_detail?job_id=c571a8c7f76a4fd4a67c103d753e2dd5"
|
83
83
|
cluster_size = 5
|
84
84
|
|
85
|
-
mock(Mortar::Auth.api).
|
85
|
+
mock(Mortar::Auth.api).post_pig_job_new_cluster("myproject", "my_script", is_a(String),cluster_size,
|
86
86
|
:pig_version => "0.9",
|
87
87
|
:project_script_path => be_a_kind_of(String),
|
88
88
|
:parameters => match_array([{"name" => "FIRST_PARAM", "value" => "FOO"}, {"name" => "SECOND_PARAM", "value" => "BAR"}]),
|
@@ -142,7 +142,7 @@ STDERR
|
|
142
142
|
job_url = "http://127.0.0.1:5000/jobs/job_detail?job_id=c571a8c7f76a4fd4a67c103d753e2dd5"
|
143
143
|
cluster_size = 5
|
144
144
|
|
145
|
-
mock(Mortar::Auth.api).
|
145
|
+
mock(Mortar::Auth.api).post_pig_job_new_cluster("myproject", "my_script", is_a(String),cluster_size,
|
146
146
|
:pig_version => "0.9",
|
147
147
|
:project_script_path => be_a_kind_of(String),
|
148
148
|
:parameters => match_array([{"name" => "FIRST_PARAM", "value" => "FOO"}, {"name" => "SECOND_PARAM", "value" => "BAR"}]),
|
@@ -178,7 +178,7 @@ STDOUT
|
|
178
178
|
job_url = "http://127.0.0.1:5000/jobs/job_detail?job_id=c571a8c7f76a4fd4a67c103d753e2dd5"
|
179
179
|
cluster_size = 5
|
180
180
|
|
181
|
-
mock(Mortar::Auth.api).
|
181
|
+
mock(Mortar::Auth.api).post_pig_job_new_cluster("myproject", "my_script", is_a(String),cluster_size,
|
182
182
|
:pig_version => "0.9",
|
183
183
|
:project_script_path => be_a_kind_of(String),
|
184
184
|
:parameters => match_array([{"name" => "FIRST_PARAM", "value" => "FOO"}, {"name" => "SECOND_PARAM", "value" => "BAR"}]),
|
@@ -214,7 +214,7 @@ STDOUT
|
|
214
214
|
job_url = "http://127.0.0.1:5000/jobs/job_detail?job_id=c571a8c7f76a4fd4a67c103d753e2dd5"
|
215
215
|
cluster_id = "e2790e7e8c7d48e39157238d58191346"
|
216
216
|
|
217
|
-
mock(Mortar::Auth.api).
|
217
|
+
mock(Mortar::Auth.api).post_pig_job_existing_cluster("myproject", "my_script", is_a(String), cluster_id,
|
218
218
|
:pig_version => "0.9",
|
219
219
|
:project_script_path => be_a_kind_of(String),
|
220
220
|
:parameters => [],
|
@@ -248,7 +248,7 @@ STDOUT
|
|
248
248
|
job_url = "http://127.0.0.1:5000/jobs/job_detail?job_id=c571a8c7f76a4fd4a67c103d753e2dd5"
|
249
249
|
cluster_id = "e2790e7e8c7d48e39157238d58191346"
|
250
250
|
|
251
|
-
mock(Mortar::Auth.api).
|
251
|
+
mock(Mortar::Auth.api).post_pig_job_existing_cluster("myproject", "my_script", is_a(String), cluster_id,
|
252
252
|
:pig_version => "0.9",
|
253
253
|
:project_script_path => be_a_kind_of(String),
|
254
254
|
:parameters => [],
|
@@ -282,7 +282,7 @@ STDOUT
|
|
282
282
|
cluster_size = 2
|
283
283
|
|
284
284
|
mock(Mortar::Auth.api).get_clusters() {Excon::Response.new(:body => {'clusters' => []})}
|
285
|
-
mock(Mortar::Auth.api).
|
285
|
+
mock(Mortar::Auth.api).post_pig_job_new_cluster("myproject", "my_script", is_a(String), cluster_size,
|
286
286
|
:pig_version => "0.9",
|
287
287
|
:project_script_path => be_a_kind_of(String),
|
288
288
|
:parameters => [],
|
@@ -320,7 +320,7 @@ STDOUT
|
|
320
320
|
cluster_size = 2
|
321
321
|
|
322
322
|
mock(Mortar::Auth.api).get_clusters() {Excon::Response.new(:body => {'clusters' => []})}
|
323
|
-
mock(Mortar::Auth.api).
|
323
|
+
mock(Mortar::Auth.api).post_pig_job_new_cluster("myproject", "my_script", is_a(String), cluster_size,
|
324
324
|
:pig_version => "0.9",
|
325
325
|
:project_script_path => be_a_kind_of(String),
|
326
326
|
:parameters => [],
|
@@ -358,7 +358,7 @@ STDOUT
|
|
358
358
|
job_url = "http://127.0.0.1:5000/jobs/job_detail?job_id=c571a8c7f76a4fd4a67c103d753e2dd5"
|
359
359
|
cluster_id = "e2790e7e8c7d48e39157238d58191346"
|
360
360
|
|
361
|
-
mock(Mortar::Auth.api).
|
361
|
+
mock(Mortar::Auth.api).post_pig_job_existing_cluster("myproject", "my_script", is_a(String), cluster_id, :pig_version => "0.9", :project_script_path => be_a_kind_of(String), :parameters => [], :notify_on_job_finish => false, :is_control_script=>false) {Excon::Response.new(:body => {"job_id" => job_id, "web_job_url" => job_url})}
|
362
362
|
|
363
363
|
write_file(File.join(p.pigscripts_path, "my_script.pig"))
|
364
364
|
stderr, stdout = execute("jobs:run pigscripts/my_script.pig --clusterid e2790e7e8c7d48e39157238d58191346 -d", p, @git)
|
@@ -410,7 +410,7 @@ STDOUT
|
|
410
410
|
'job_name' => "", 'start_timestamp' => ""} ], 'status_code' => huge_busy_cluster_status }
|
411
411
|
]})
|
412
412
|
}
|
413
|
-
mock(Mortar::Auth.api).
|
413
|
+
mock(Mortar::Auth.api).post_pig_job_existing_cluster("myproject", "my_script", is_a(String), large_cluster_id,
|
414
414
|
:pig_version => "0.9",
|
415
415
|
:project_script_path => be_a_kind_of(String),
|
416
416
|
:parameters => [],
|
@@ -444,7 +444,7 @@ STDOUT
|
|
444
444
|
job_id = "c571a8c7f76a4fd4a67c103d753e2dd5"
|
445
445
|
cluster_size = 5
|
446
446
|
|
447
|
-
mock(Mortar::Auth.api).
|
447
|
+
mock(Mortar::Auth.api).post_pig_job_new_cluster("myproject", "my_script", is_a(String), cluster_size,
|
448
448
|
:pig_version => "0.9",
|
449
449
|
:project_script_path => be_a_kind_of(String),
|
450
450
|
:parameters => match_array([{"name" => "FIRST", "value" => "FOO"}, {"name" => "SECOND", "value" => "BAR"}, {"name" => "THIRD", "value" => "BEAR"}]),
|
@@ -472,7 +472,7 @@ PARAMS
|
|
472
472
|
job_id = "c571a8c7f76a4fd4a67c103d753e2dd5"
|
473
473
|
cluster_size = 5
|
474
474
|
|
475
|
-
mock(Mortar::Auth.api).
|
475
|
+
mock(Mortar::Auth.api).post_pig_job_new_cluster("myproject", "my_script", is_a(String), cluster_size,
|
476
476
|
:pig_version => "0.9",
|
477
477
|
:project_script_path => be_a_kind_of(String),
|
478
478
|
:parameters => match_array([{"name" => "FIRST", "value" => "FOO"}, {"name" => "SECOND", "value" => "BAR"}, {"name" => "THIRD", "value" => "BEAR"}]),
|
@@ -528,7 +528,7 @@ STDERR
|
|
528
528
|
|
529
529
|
mock(@git).sync_embedded_project.with_any_args.times(1) { "somewhere_over_the_rainbow" }
|
530
530
|
|
531
|
-
mock(Mortar::Auth.api).
|
531
|
+
mock(Mortar::Auth.api).post_pig_job_new_cluster("myproject", "my_script", is_a(String), cluster_size,
|
532
532
|
:pig_version => "0.9",
|
533
533
|
:project_script_path => be_a_kind_of(String),
|
534
534
|
:parameters => match_array([{"name" => "FIRST_PARAM", "value" => "FOO"}, {"name" => "SECOND_PARAM", "value" => "BAR"}]),
|
@@ -289,29 +289,67 @@ STDERR
|
|
289
289
|
end
|
290
290
|
end
|
291
291
|
|
292
|
-
it "Runs script
|
292
|
+
it "Runs script with old pig-style parameters passed to luigi script" do
|
293
293
|
with_git_initialized_project do |p|
|
294
|
+
ENV['MORTAR_LUIGI_GIT_REF'] = nil
|
294
295
|
script_name = "some_luigi_script"
|
295
296
|
script_path = File.join(p.luigiscripts_path, "#{script_name}.py")
|
296
297
|
write_file(script_path)
|
297
298
|
luigi_script = Mortar::Project::LuigiScript.new(script_name, script_path)
|
299
|
+
config_parameters = []
|
298
300
|
mock(Mortar::Project::LuigiScript).new(script_name, script_path).returns(luigi_script)
|
301
|
+
any_instance_of(Mortar::Command::Local) do |u|
|
302
|
+
mock(u).config_parameters.returns(config_parameters)
|
303
|
+
end
|
299
304
|
any_instance_of(Mortar::Local::Python) do |u|
|
300
305
|
mock(u).run_luigi_script(luigi_script, %W{--myoption 2 --myotheroption 3})
|
306
|
+
mock(u).run_stillson_luigi_client_cfg_expansion(luigi_script, config_parameters).returns(true)
|
301
307
|
end
|
302
308
|
any_instance_of(Mortar::Local::Controller) do |u|
|
303
309
|
mock(u).install_and_configure(is_a(Mortar::PigVersion::Pig09),'luigi')
|
310
|
+
mock(u).require_aws_keys()
|
304
311
|
end
|
305
312
|
any_instance_of(Mortar::Command::Local) do |u|
|
306
313
|
mock(u).sync_code_with_cloud().returns("some-git-ref")
|
307
314
|
end
|
308
315
|
ENV['MORTAR_LUIGI_GIT_REF'].should be_nil
|
309
316
|
stderr, stdout = execute("local:luigi some_luigi_script -p myoption=2 -p myotheroption=3", p)
|
310
|
-
stderr.should ==
|
311
|
-
|
317
|
+
stderr.should == <<-STDERR
|
318
|
+
[DEPRECATION] Passing luigi parameters with -p is deprecated. Please pass them directly (e.g. --myparam myvalue)
|
319
|
+
STDERR
|
320
|
+
ENV['MORTAR_LUIGI_GIT_REF'].should == "some-git-ref"
|
312
321
|
end
|
313
322
|
end
|
314
323
|
|
324
|
+
it "Runs script with new luigi-style parameters passed to luigi script" do
|
325
|
+
with_git_initialized_project do |p|
|
326
|
+
ENV['MORTAR_LUIGI_GIT_REF'] = nil
|
327
|
+
script_name = "some_luigi_script"
|
328
|
+
script_path = File.join(p.luigiscripts_path, "#{script_name}.py")
|
329
|
+
write_file(script_path)
|
330
|
+
luigi_script = Mortar::Project::LuigiScript.new(script_name, script_path)
|
331
|
+
config_parameters = []
|
332
|
+
mock(Mortar::Project::LuigiScript).new(script_name, script_path).returns(luigi_script)
|
333
|
+
any_instance_of(Mortar::Command::Local) do |u|
|
334
|
+
mock(u).config_parameters.returns(config_parameters)
|
335
|
+
end
|
336
|
+
any_instance_of(Mortar::Local::Python) do |u|
|
337
|
+
mock(u).run_stillson_luigi_client_cfg_expansion(luigi_script, config_parameters).returns(true)
|
338
|
+
mock(u).run_luigi_script(luigi_script, %W{--myoption 2 --myotheroption 3})
|
339
|
+
end
|
340
|
+
any_instance_of(Mortar::Local::Controller) do |u|
|
341
|
+
mock(u).install_and_configure(is_a(Mortar::PigVersion::Pig09),'luigi')
|
342
|
+
mock(u).require_aws_keys()
|
343
|
+
end
|
344
|
+
any_instance_of(Mortar::Command::Local) do |u|
|
345
|
+
mock(u).sync_code_with_cloud().returns("some-git-ref")
|
346
|
+
end
|
347
|
+
ENV['MORTAR_LUIGI_GIT_REF'].should be_nil
|
348
|
+
stderr, stdout = execute("local:luigi some_luigi_script --myoption 2 --myotheroption 3", p)
|
349
|
+
stderr.should == ""
|
350
|
+
ENV['MORTAR_LUIGI_GIT_REF'].should == "some-git-ref"
|
351
|
+
end
|
352
|
+
end
|
315
353
|
|
316
354
|
end
|
317
355
|
|