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.
- 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
|
|