neptune 0.1.4 → 0.2.0
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/README +4 -0
- data/bin/neptune +7 -0
- data/doc/AppControllerClient.html +113 -22
- data/doc/{Kernel.html → AppControllerException.html} +23 -55
- data/doc/BabelHelper.html +707 -0
- data/doc/BadConfigurationException.html +142 -0
- data/doc/CommonFunctions.html +121 -33
- data/doc/FileNotFoundException.html +142 -0
- data/doc/NeptuneHelper.html +1102 -0
- data/doc/Object.html +94 -749
- data/doc/bin/neptune.html +3 -1
- data/doc/created.rid +7 -5
- data/doc/index.html +73 -25
- data/doc/lib/app_controller_client_rb.html +1 -1
- data/doc/lib/babel_rb.html +68 -0
- data/doc/lib/common_functions_rb.html +3 -1
- data/doc/lib/custom_exceptions_rb.html +54 -0
- data/doc/lib/neptune_rb.html +3 -1
- data/lib/app_controller_client.rb +28 -10
- data/lib/babel.rb +260 -0
- data/lib/common_functions.rb +42 -28
- data/lib/custom_exceptions.rb +10 -0
- data/lib/neptune.rb +371 -304
- data/test/unit/test_app_controller_client.rb +9 -9
- data/test/unit/test_babel.rb +154 -0
- data/test/unit/test_common_functions.rb +39 -75
- data/test/unit/test_neptune.rb +168 -76
- data/test/unit/ts_all.rb +5 -0
- metadata +32 -8
@@ -41,7 +41,7 @@ class TestAppControllerClient < Test::Unit::TestCase
|
|
41
41
|
no_retry_on_exception = false
|
42
42
|
|
43
43
|
call_number = 0
|
44
|
-
assert_nothing_raised(
|
44
|
+
assert_nothing_raised(AppControllerException) {
|
45
45
|
@client.make_call(no_timeout, retry_on_exception) {
|
46
46
|
call_number += 1
|
47
47
|
case call_number
|
@@ -57,13 +57,13 @@ class TestAppControllerClient < Test::Unit::TestCase
|
|
57
57
|
}
|
58
58
|
}
|
59
59
|
|
60
|
-
assert_raise(
|
60
|
+
assert_raise(AppControllerException) {
|
61
61
|
@client.make_call(no_timeout, no_retry_on_exception) {
|
62
62
|
raise Errno::ECONNREFUSED
|
63
63
|
}
|
64
64
|
}
|
65
65
|
|
66
|
-
assert_raise(
|
66
|
+
assert_raise(AppControllerException) {
|
67
67
|
@client.make_call(no_timeout, no_retry_on_exception) {
|
68
68
|
raise Exception
|
69
69
|
}
|
@@ -76,31 +76,31 @@ class TestAppControllerClient < Test::Unit::TestCase
|
|
76
76
|
# result unless it has 'Error:' in it. If it does, it aborts execution.
|
77
77
|
def test_start_neptune_job
|
78
78
|
assert(@client.start_neptune_job(@job_data_ok))
|
79
|
-
assert_raise(
|
79
|
+
assert_raise(AppControllerException) { @client.start_neptune_job(@job_data_err) }
|
80
80
|
end
|
81
81
|
|
82
82
|
def test_put_input
|
83
83
|
assert(@client.put_input(@job_data_ok))
|
84
|
-
assert_raise(
|
84
|
+
assert_raise(AppControllerException) { @client.put_input(@job_data_err) }
|
85
85
|
end
|
86
86
|
|
87
87
|
def test_get_output
|
88
88
|
assert(@client.get_output(@job_data_ok))
|
89
|
-
assert_raise(
|
89
|
+
assert_raise(AppControllerException) { @client.get_output(@job_data_err) }
|
90
90
|
end
|
91
91
|
|
92
92
|
def test_get_acl
|
93
93
|
assert(@client.get_acl(@job_data_ok))
|
94
|
-
assert_raise(
|
94
|
+
assert_raise(AppControllerException) { @client.get_acl(@job_data_err) }
|
95
95
|
end
|
96
96
|
|
97
97
|
def test_set_acl
|
98
98
|
assert(@client.set_acl(@job_data_ok))
|
99
|
-
assert_raise(
|
99
|
+
assert_raise(AppControllerException) { @client.set_acl(@job_data_err) }
|
100
100
|
end
|
101
101
|
|
102
102
|
def test_compile_code
|
103
103
|
assert(@client.compile_code(@job_data_ok))
|
104
|
-
assert_raise(
|
104
|
+
assert_raise(AppControllerException) { @client.compile_code(@job_data_err) }
|
105
105
|
end
|
106
106
|
end
|
@@ -0,0 +1,154 @@
|
|
1
|
+
# Programmer: Chris Bunch (cgb@cs.ucsb.edu)
|
2
|
+
|
3
|
+
$:.unshift File.join(File.dirname(__FILE__), "..", "..", "lib")
|
4
|
+
require 'babel'
|
5
|
+
|
6
|
+
require 'test/unit'
|
7
|
+
|
8
|
+
|
9
|
+
class TestBabel < Test::Unit::TestCase
|
10
|
+
def test_bad_babel_params
|
11
|
+
job_data_no_code_param = {}
|
12
|
+
assert_raise(BadConfigurationException) {
|
13
|
+
# Since babel is using futures/promises, the babel invocation won't
|
14
|
+
# actually throw the exception to us unless we use the value in any
|
15
|
+
# way - so just print it, knowing it will never get to stdout.
|
16
|
+
a = babel(job_data_no_code_param)
|
17
|
+
Kernel.puts(a)
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_generate_output
|
22
|
+
# Since output is generated randomly, make it non-random for now.
|
23
|
+
commonfunctions = flexmock(CommonFunctions)
|
24
|
+
commonfunctions.should_receive(:get_random_alphanumeric).and_return(10)
|
25
|
+
|
26
|
+
job_data_local_code = {"@code" => "boo.rb"}
|
27
|
+
|
28
|
+
# If neither @bucket_name nor the BABEL_BUCKET_NAME env var are specified,
|
29
|
+
# this should fail.
|
30
|
+
assert_raise(BadConfigurationException) {
|
31
|
+
BabelHelper.generate_output_location(job_data_local_code)
|
32
|
+
}
|
33
|
+
|
34
|
+
# Now specify the @bucket_name - it should succeed.
|
35
|
+
job_data_local_code["@bucket_name"] = "/baz"
|
36
|
+
expected_local = "/baz/babel/temp-10"
|
37
|
+
actual_local_1 = BabelHelper.generate_output_location(job_data_local_code)
|
38
|
+
assert_equal(expected_local, actual_local_1)
|
39
|
+
|
40
|
+
# Specifying the BABEL_BUCKET_NAME environment variable should be OK.
|
41
|
+
job_data_local_code["@bucket_name"] = nil
|
42
|
+
ENV['BABEL_BUCKET_NAME'] = "/baz"
|
43
|
+
actual_local_2 = BabelHelper.generate_output_location(job_data_local_code)
|
44
|
+
assert_equal(expected_local, actual_local_2)
|
45
|
+
|
46
|
+
# Not putting the initial slash on the bucket name should be fine too.
|
47
|
+
ENV['BABEL_BUCKET_NAME'] = "baz"
|
48
|
+
actual_local_3 = BabelHelper.generate_output_location(job_data_local_code)
|
49
|
+
assert_equal(expected_local, actual_local_3)
|
50
|
+
|
51
|
+
# Finally, if we run a job and specify remote code, that should be used
|
52
|
+
# as the bucket.
|
53
|
+
job_data_remote_code = {"@code" => "/baz/boo/code.baz", "@is_remote" => true}
|
54
|
+
expected_remote = "/baz/babel/temp-10"
|
55
|
+
|
56
|
+
actual_remote = BabelHelper.generate_output_location(job_data_remote_code)
|
57
|
+
assert_equal(expected_remote, actual_remote)
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_put_code
|
61
|
+
job_data = {"@code" => "/baz/boo/code.baz", "@bucket_name" => "/remote"}
|
62
|
+
|
63
|
+
neptune_params = {
|
64
|
+
:type => "input",
|
65
|
+
:local => "/baz/boo",
|
66
|
+
:remote => "/remote/babel/baz/boo",
|
67
|
+
:bucket_name => "/remote",
|
68
|
+
:code => "/baz/boo/code.baz"
|
69
|
+
}
|
70
|
+
|
71
|
+
kernel = flexmock(Kernel)
|
72
|
+
kernel.should_receive(:neptune).with(neptune_params)
|
73
|
+
|
74
|
+
expected = "/remote/babel/baz/boo/code.baz"
|
75
|
+
actual = BabelHelper.put_code(job_data)
|
76
|
+
assert_equal(expected, actual)
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_put_inputs
|
80
|
+
# If we specify no inputs or no file inputs, we should get back exactly what
|
81
|
+
# we give it
|
82
|
+
job_data = {"@code" => "/baz/boo/code.baz", "@bucket_name" => "/remote"}
|
83
|
+
actual_1 = BabelHelper.put_inputs(job_data)
|
84
|
+
assert_equal(job_data, actual_1)
|
85
|
+
|
86
|
+
job_data["@argv"] = ["boo", "baz", "gbaz"]
|
87
|
+
actual_2 = BabelHelper.put_inputs(job_data)
|
88
|
+
assert_equal(job_data, actual_2)
|
89
|
+
|
90
|
+
# If we specify inputs on the file system, they should be uploaded and replaced
|
91
|
+
# with remote file locations
|
92
|
+
neptune_params = {
|
93
|
+
:type => "input",
|
94
|
+
:local => "/baz",
|
95
|
+
:remote => "/remote/babel/baz",
|
96
|
+
:bucket_name => "/remote",
|
97
|
+
:code => "/baz/boo/code.baz",
|
98
|
+
:argv => ["boo", "/baz", "gbaz"]
|
99
|
+
}
|
100
|
+
|
101
|
+
kernel = flexmock(Kernel)
|
102
|
+
kernel.should_receive(:neptune).with(neptune_params)
|
103
|
+
|
104
|
+
job_data["@argv"] = ["boo", "/baz", "gbaz"]
|
105
|
+
expected = job_data.dup
|
106
|
+
expected["@argv"] = ["boo", "/remote/babel/baz", "gbaz"]
|
107
|
+
actual_3 = BabelHelper.put_inputs(job_data.dup)
|
108
|
+
assert_equal(expected, actual_3)
|
109
|
+
end
|
110
|
+
|
111
|
+
def test_run_job
|
112
|
+
job_data = {
|
113
|
+
"@code" => "/baz/boo/code.baz",
|
114
|
+
"@argv" => ["boo", "/remote/babel/baz", "gbaz"]
|
115
|
+
}
|
116
|
+
|
117
|
+
neptune_params = {
|
118
|
+
:type => "babel",
|
119
|
+
:code => "/baz/boo/code.baz",
|
120
|
+
:argv => ["boo", "/remote/babel/baz", "gbaz"],
|
121
|
+
:run_local => true,
|
122
|
+
:engine => "executor-sqs"
|
123
|
+
}
|
124
|
+
|
125
|
+
result = { :result => :success }
|
126
|
+
kernel = flexmock(Kernel)
|
127
|
+
kernel.should_receive(:neptune).with(neptune_params).and_return(result)
|
128
|
+
|
129
|
+
expected = :success
|
130
|
+
actual = BabelHelper.run_job(job_data)[:result]
|
131
|
+
assert_equal(expected, actual)
|
132
|
+
end
|
133
|
+
|
134
|
+
def test_get_output
|
135
|
+
job_data = {
|
136
|
+
"@output" => "/baz/boo/code.baz"
|
137
|
+
}
|
138
|
+
|
139
|
+
neptune_params = {
|
140
|
+
:type => "output",
|
141
|
+
:output => "/baz/boo/code.baz"
|
142
|
+
}
|
143
|
+
|
144
|
+
result1 = { :output => DOES_NOT_EXIST }
|
145
|
+
result2 = { :output => "output goes here" }
|
146
|
+
kernel = flexmock(Kernel)
|
147
|
+
kernel.should_receive(:neptune).with(neptune_params).and_return(result1, result2)
|
148
|
+
kernel.should_receive(:sleep).and_return()
|
149
|
+
|
150
|
+
expected = "output goes here"
|
151
|
+
actual = BabelHelper.wait_and_get_output(job_data)
|
152
|
+
assert_equal(expected, actual)
|
153
|
+
end
|
154
|
+
end
|
@@ -7,100 +7,64 @@ require 'test/unit'
|
|
7
7
|
|
8
8
|
SECRET = "hey-its-a-secret"
|
9
9
|
|
10
|
-
module FakeCommonFunctions
|
11
|
-
def self.get_from_yaml(a, b, c)
|
12
|
-
end
|
13
10
|
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
class TestCommonFunctions < Test::Unit::TestCase
|
12
|
+
def setup
|
13
|
+
@commonfunctions = flexmock(CommonFunctions)
|
14
|
+
@commonfunctions.should_receive(:scp_file).and_return()
|
15
|
+
@commonfunctions.should_receive(:shell).and_return()
|
17
16
|
|
18
|
-
|
19
|
-
|
17
|
+
@file = flexmock(File)
|
18
|
+
@file.should_receive(:expand_path).and_return("")
|
20
19
|
|
21
|
-
|
22
|
-
|
23
|
-
end
|
20
|
+
@fileutils = flexmock(FileUtils)
|
21
|
+
@fileutils.should_receive(:rm_f).and_return()
|
24
22
|
|
25
|
-
|
26
|
-
if name.include?("OK") or name.include?("BAD-TAG") or name.include?("FAIL")
|
27
|
-
return true
|
28
|
-
elsif name.include?("retval")
|
29
|
-
# The first time around, tell the caller that the file didn't exist so
|
30
|
-
# that it sleeps. The next time around, tell it that the file does exist.
|
31
|
-
if @@exists_checks_done.zero?
|
32
|
-
@@exists_checks_done += 1
|
33
|
-
return false
|
34
|
-
else
|
35
|
-
return true
|
36
|
-
end
|
37
|
-
else
|
38
|
-
return false
|
39
|
-
end
|
40
|
-
end
|
23
|
+
@yaml = flexmock(YAML)
|
41
24
|
|
42
|
-
|
43
|
-
if name.include?("retval")
|
44
|
-
return "0\n"
|
45
|
-
else
|
46
|
-
return "1\n"
|
47
|
-
end
|
25
|
+
@yaml_info = { :secret => SECRET, :shadow => SECRET }
|
48
26
|
end
|
49
|
-
end
|
50
27
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
end
|
55
|
-
end
|
28
|
+
def test_scp_to_shadow
|
29
|
+
@file.should_receive(:exists?).and_return(true)
|
30
|
+
@yaml.should_receive(:load_file).and_return(@yaml_info)
|
56
31
|
|
57
|
-
|
58
|
-
|
59
|
-
|
32
|
+
assert_nothing_raised(Exception) {
|
33
|
+
CommonFunctions.scp_to_shadow("", "", "", "")
|
34
|
+
}
|
60
35
|
end
|
61
36
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
end
|
37
|
+
def test_get_secret_key_file_exists
|
38
|
+
@file.should_receive(:exists?).and_return(true)
|
39
|
+
@yaml.should_receive(:load_file).and_return(@yaml_info)
|
66
40
|
|
67
|
-
|
68
|
-
def self.load_file(filename)
|
69
|
-
if filename.include?("OK")
|
70
|
-
return { :secret => SECRET, :shadow => SECRET }
|
71
|
-
elsif filename.include?("BAD-TAG")
|
72
|
-
return {}
|
73
|
-
else
|
74
|
-
raise ArgumentError
|
75
|
-
end
|
41
|
+
assert_equal(SECRET, CommonFunctions.get_secret_key("", required=true))
|
76
42
|
end
|
77
|
-
end
|
78
43
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
CommonFunctions.scp_to_shadow("OK", "OK", "OK", "OK",
|
83
|
-
file=FakeFile,
|
84
|
-
get_from_yaml=FakeCommonFunctions.method(:get_from_yaml),
|
85
|
-
scp_file=FakeCommonFunctions.method(:scp_file))
|
44
|
+
def test_get_secret_key_malformed_yaml
|
45
|
+
assert_raise(BadConfigurationException) {
|
46
|
+
CommonFunctions.get_secret_key("", required=true)
|
86
47
|
}
|
87
48
|
end
|
88
49
|
|
89
|
-
def
|
90
|
-
|
91
|
-
|
50
|
+
def test_get_secret_key_wrong_tag
|
51
|
+
assert_raise(BadConfigurationException) {
|
52
|
+
CommonFunctions.get_secret_key("", required=true)
|
53
|
+
}
|
92
54
|
|
93
|
-
|
94
|
-
required=true, FakeFile, FakeYAML) }
|
55
|
+
@file.should_receive(:exists?).and_return(true)
|
95
56
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
57
|
+
yaml_info_no_secret = { :shadow => SECRET }
|
58
|
+
@yaml.should_receive(:load_file).and_return(yaml_info_no_secret)
|
59
|
+
|
60
|
+
assert_nil(CommonFunctions.get_secret_key("", required=false))
|
61
|
+
end
|
100
62
|
|
101
|
-
|
102
|
-
|
103
|
-
|
63
|
+
def test_get_secret_key_file_doesnt_exist
|
64
|
+
@file.should_receive(:exists).and_return(false)
|
65
|
+
|
66
|
+
assert_raise(BadConfigurationException) {
|
67
|
+
CommonFunctions.get_secret_key("", required=true)
|
104
68
|
}
|
105
69
|
end
|
106
70
|
end
|
data/test/unit/test_neptune.rb
CHANGED
@@ -5,182 +5,195 @@ require 'neptune'
|
|
5
5
|
|
6
6
|
require 'test/unit'
|
7
7
|
|
8
|
-
class FakeAppControllerClient
|
9
|
-
def initialize(a, b)
|
10
|
-
end
|
11
8
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
if method_names.include?(id.to_s)
|
18
|
-
return true
|
19
|
-
else
|
20
|
-
super
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
9
|
+
class TestNeptune < Test::Unit::TestCase
|
10
|
+
def setup
|
11
|
+
@commonfunctions = flexmock(CommonFunctions)
|
12
|
+
@commonfunctions.should_receive(:scp_to_shadow).and_return()
|
13
|
+
@commonfunctions.should_receive(:shell).and_return()
|
24
14
|
|
25
|
-
|
26
|
-
|
27
|
-
return path
|
28
|
-
end
|
15
|
+
@file = flexmock(File)
|
16
|
+
@file.should_receive(:expand_path).and_return("")
|
29
17
|
|
30
|
-
|
31
|
-
|
32
|
-
return true
|
33
|
-
else
|
34
|
-
return false
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
18
|
+
@fileutils = flexmock(FileUtils)
|
19
|
+
@fileutils.should_receive(:rm_f).and_return()
|
38
20
|
|
39
|
-
|
40
|
-
|
41
|
-
end
|
42
|
-
end
|
21
|
+
@kernel = flexmock(Kernel)
|
22
|
+
@kernel.should_receive(:puts).and_return()
|
43
23
|
|
44
|
-
|
45
|
-
|
24
|
+
@yaml_info = {:load_balancer => "127.0.0.1",
|
25
|
+
:shadow => "127.0.0.1",
|
26
|
+
:secret => @secret,
|
27
|
+
:db_master => "node-1",
|
28
|
+
:table => "cassandra",
|
29
|
+
:instance_id => "i-FOOBARZ"}
|
30
|
+
|
31
|
+
@yaml = flexmock(YAML)
|
32
|
+
@yaml.should_receive(:load_file).and_return(@yaml_info)
|
46
33
|
end
|
47
|
-
end
|
48
34
|
|
49
|
-
class TestNeptune < Test::Unit::TestCase
|
50
35
|
def test_do_preprocessing
|
51
36
|
# Try a job that needs preprocessing
|
52
37
|
job_data_1 = {"@type" => "ssa", "@trajectories" => 10}
|
53
|
-
assert_nothing_raised(
|
38
|
+
assert_nothing_raised(BadConfigurationException) {
|
39
|
+
NeptuneHelper.do_preprocessing(job_data_1, nil)
|
40
|
+
}
|
54
41
|
|
55
42
|
# Now try a job that doesn't need it
|
56
43
|
job_data_2 = {"@type" => "input"}
|
57
|
-
assert_nothing_raised(
|
44
|
+
assert_nothing_raised(BadConfigurationException) {
|
45
|
+
NeptuneHelper.do_preprocessing(job_data_2, nil)
|
46
|
+
}
|
58
47
|
end
|
59
48
|
|
60
49
|
def test_preprocess_compile
|
61
50
|
end
|
62
51
|
|
63
|
-
def
|
52
|
+
def test_preprocess_erlang_errors
|
53
|
+
@file.should_receive(:exists?).and_return(false)
|
54
|
+
|
64
55
|
# Try a job where we didn't specify the code
|
65
56
|
job_data_1 = {}
|
66
|
-
assert_raise(
|
67
|
-
preprocess_erlang(job_data_1,
|
57
|
+
assert_raise(BadConfigurationException) {
|
58
|
+
NeptuneHelper.preprocess_erlang(job_data_1, nil)
|
68
59
|
}
|
69
60
|
|
70
61
|
# Try a job where the source doesn't exist
|
71
62
|
job_data_2 = {"@code" => "NOT-EXISTANT"}
|
72
|
-
assert_raise(
|
73
|
-
preprocess_erlang(job_data_2,
|
63
|
+
assert_raise(BadConfigurationException) {
|
64
|
+
NeptuneHelper.preprocess_erlang(job_data_2, nil)
|
74
65
|
}
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_preprocess_erlang_no_errors
|
69
|
+
@file.should_receive(:exists?).and_return(true)
|
75
70
|
|
76
71
|
# Now try a job where the source does exist
|
77
72
|
job_data_3 = {"@code" => "EXISTS"}
|
78
|
-
assert_nothing_raised(
|
79
|
-
preprocess_erlang(job_data_3,
|
73
|
+
assert_nothing_raised(BadConfigurationException) {
|
74
|
+
NeptuneHelper.preprocess_erlang(job_data_3, nil)
|
80
75
|
}
|
81
76
|
end
|
82
77
|
|
83
78
|
def test_preprocess_mpi
|
84
79
|
# not specifying nodes to use or procs to use should throw an error
|
85
80
|
job_data_1 = {}
|
86
|
-
assert_raise(
|
81
|
+
assert_raise(BadConfigurationException) {
|
82
|
+
NeptuneHelper.preprocess_mpi(job_data_1, nil)
|
83
|
+
}
|
87
84
|
|
88
85
|
# not specifying procs to use should throw an error
|
89
86
|
job_data_2 = {"@nodes_to_use" => 4}
|
90
|
-
assert_raise(
|
87
|
+
assert_raise(BadConfigurationException) {
|
88
|
+
NeptuneHelper.preprocess_mpi(job_data_2, nil)
|
89
|
+
}
|
91
90
|
|
92
91
|
# specifying procs to use == nodes to use should not throw an error
|
93
92
|
job_data_3 = {"@nodes_to_use" => 4, "@procs_to_use" => 4}
|
94
|
-
assert_equal(job_data_3, preprocess_mpi(job_data_3))
|
93
|
+
assert_equal(job_data_3, NeptuneHelper.preprocess_mpi(job_data_3, nil))
|
95
94
|
|
96
95
|
# specifying procs to use < nodes to use should throw an error
|
97
96
|
job_data_4 = {"@nodes_to_use" => 4, "@procs_to_use" => 1}
|
98
|
-
assert_raise(
|
97
|
+
assert_raise(BadConfigurationException) {
|
98
|
+
NeptuneHelper.preprocess_mpi(job_data_4, nil)
|
99
|
+
}
|
99
100
|
|
100
101
|
# specifying an empty string for argv should be ok
|
101
102
|
job_data_5 = {"@nodes_to_use" => 4, "@procs_to_use" => 4, "@argv" => ""}
|
102
|
-
assert_equal(job_data_5, preprocess_mpi(job_data_5))
|
103
|
+
assert_equal(job_data_5, NeptuneHelper.preprocess_mpi(job_data_5, nil))
|
103
104
|
|
104
105
|
# specifying an empty array for argv should be ok
|
105
106
|
job_data_6 = {"@nodes_to_use" => 4, "@procs_to_use" => 4, "@argv" => []}
|
106
107
|
expected_job_data_6 = job_data_6.dup
|
107
108
|
expected_job_data_6["@argv"] = ""
|
108
|
-
assert_equal(expected_job_data_6, preprocess_mpi(job_data_6))
|
109
|
+
assert_equal(expected_job_data_6, NeptuneHelper.preprocess_mpi(job_data_6, nil))
|
109
110
|
|
110
111
|
# specifying something that's not a string or array for argv should throw
|
111
112
|
# an error
|
112
113
|
job_data_7 = {"@nodes_to_use" => 4, "@procs_to_use" => 4, "@argv" => 2}
|
113
|
-
assert_raise(
|
114
|
+
assert_raise(BadConfigurationException) {
|
115
|
+
NeptuneHelper.preprocess_mpi(job_data_7, nil)
|
116
|
+
}
|
114
117
|
|
115
118
|
# specifying a non-empty string for argv should be ok
|
116
119
|
job_data_8 = {"@nodes_to_use" => 4, "@procs_to_use" => 4, "@argv" => "--file coo"}
|
117
|
-
assert_equal(job_data_8, preprocess_mpi(job_data_8))
|
120
|
+
assert_equal(job_data_8, NeptuneHelper.preprocess_mpi(job_data_8, nil))
|
118
121
|
|
119
122
|
# specifying a non-empty array for argv should be ok
|
120
123
|
job_data_9 = {"@nodes_to_use" => 4, "@procs_to_use" => 4, "@argv" => ["--file", "coo"]}
|
121
124
|
expected_job_data_9 = job_data_9.dup
|
122
125
|
expected_job_data_9["@argv"] = "--file coo"
|
123
|
-
assert_equal(expected_job_data_9, preprocess_mpi(job_data_9))
|
126
|
+
assert_equal(expected_job_data_9, NeptuneHelper.preprocess_mpi(job_data_9, nil))
|
124
127
|
end
|
125
128
|
|
126
129
|
def test_preprocess_ssa
|
127
130
|
job_data_1 = {}
|
128
|
-
assert_raise(
|
131
|
+
assert_raise(BadConfigurationException) {
|
132
|
+
NeptuneHelper.preprocess_ssa(job_data_1, nil)
|
133
|
+
}
|
129
134
|
|
130
135
|
job_data_2 = {"@trajectories" => 10}
|
131
|
-
assert_equal(job_data_2, preprocess_ssa(job_data_2))
|
136
|
+
assert_equal(job_data_2, NeptuneHelper.preprocess_ssa(job_data_2, nil))
|
132
137
|
|
133
138
|
job_data_3 = {"@simulations" => 10}
|
134
139
|
expected_job_data_3 = {"@trajectories" => 10}
|
135
|
-
assert_equal(expected_job_data_3, preprocess_ssa(job_data_3))
|
140
|
+
assert_equal(expected_job_data_3, NeptuneHelper.preprocess_ssa(job_data_3, nil))
|
136
141
|
|
137
142
|
job_data_4 = {"@trajectories" => 10, "@simulations" => 10}
|
138
|
-
assert_raise(
|
143
|
+
assert_raise(BadConfigurationException) { NeptuneHelper.preprocess_ssa(job_data_4, nil) }
|
139
144
|
end
|
140
145
|
|
141
146
|
def test_get_job_data
|
142
147
|
params_1 = {:type => :mpi}
|
143
|
-
assert_raise(
|
148
|
+
assert_raise(BadConfigurationException) {
|
149
|
+
NeptuneHelper.get_job_data(params_1)
|
150
|
+
}
|
144
151
|
|
145
152
|
params_2 = {:type => :mpi, :output => "boo"}
|
146
|
-
assert_raise(
|
153
|
+
assert_raise(BadConfigurationException) {
|
154
|
+
NeptuneHelper.get_job_data(params_2)
|
155
|
+
}
|
147
156
|
|
148
157
|
[:mpi, :upc, :x10].each { |type|
|
149
158
|
params_3 = {:type => type, :output => "/boo"}
|
150
159
|
expected_job_data_3 = {"@type" => "mpi", "@output" => "/boo",
|
151
160
|
"@keyname" => "appscale"}
|
152
|
-
assert_equal(expected_job_data_3, get_job_data(params_3))
|
161
|
+
assert_equal(expected_job_data_3, NeptuneHelper.get_job_data(params_3))
|
153
162
|
}
|
154
163
|
|
155
164
|
params_4 = {:type => "input"}
|
156
165
|
expected_job_data_4 = {"@type" => "input", "@keyname" => "appscale"}
|
157
|
-
assert_equal(expected_job_data_4, get_job_data(params_4))
|
166
|
+
assert_equal(expected_job_data_4, NeptuneHelper.get_job_data(params_4))
|
158
167
|
|
159
168
|
params_5 = {:type => "input", :keyname => "boo"}
|
160
169
|
expected_job_data_5 = {"@type" => "input", "@keyname" => "boo"}
|
161
|
-
assert_equal(expected_job_data_5, get_job_data(params_5))
|
170
|
+
assert_equal(expected_job_data_5, NeptuneHelper.get_job_data(params_5))
|
162
171
|
|
163
172
|
params_6 = {:type => :mpi, :output => "/boo",
|
164
173
|
:nodes_to_use => {"cloud1" => 1, "cloud2" => 1}}
|
165
174
|
expected_job_data_6 = {"@type" => "mpi", "@output" => "/boo",
|
166
175
|
"@keyname" => "appscale", "@nodes_to_use" => ["cloud1", 1, "cloud2", 1]}
|
167
|
-
assert_equal(expected_job_data_6, get_job_data(params_6))
|
176
|
+
assert_equal(expected_job_data_6, NeptuneHelper.get_job_data(params_6))
|
168
177
|
end
|
169
178
|
|
170
179
|
def test_validate_storage_params
|
171
180
|
job_data_1 = {}
|
172
181
|
expected_job_data_1 = {"@storage" => "appdb"}
|
173
|
-
assert_equal(expected_job_data_1, validate_storage_params(job_data_1))
|
182
|
+
assert_equal(expected_job_data_1, NeptuneHelper.validate_storage_params(job_data_1))
|
174
183
|
|
175
184
|
job_data_2 = {"@storage" => "a bad value goes here"}
|
176
|
-
assert_raise(
|
185
|
+
assert_raise(BadConfigurationException) {
|
186
|
+
NeptuneHelper.validate_storage_params(job_data_2)
|
187
|
+
}
|
177
188
|
|
178
189
|
job_data_3 = {"@storage" => "s3"}
|
179
|
-
assert_raise(
|
190
|
+
assert_raise(BadConfigurationException) {
|
191
|
+
NeptuneHelper.validate_storage_params(job_data_3)
|
192
|
+
}
|
180
193
|
|
181
194
|
job_data_4 = {"@storage" => "s3", "@EC2_ACCESS_KEY" => "a",
|
182
195
|
"@EC2_SECRET_KEY" => "b", "@S3_URL" => "c"}
|
183
|
-
assert_equal(job_data_4, validate_storage_params(job_data_4))
|
196
|
+
assert_equal(job_data_4, NeptuneHelper.validate_storage_params(job_data_4))
|
184
197
|
|
185
198
|
ENV['EC2_ACCESS_KEY'] = "a"
|
186
199
|
ENV['EC2_SECRET_KEY'] = "b"
|
@@ -190,7 +203,7 @@ class TestNeptune < Test::Unit::TestCase
|
|
190
203
|
job_data_5 = {"@storage" => storage}
|
191
204
|
expected_job_data_5 = {"@storage" => "s3", "@EC2_ACCESS_KEY" => "a",
|
192
205
|
"@EC2_SECRET_KEY" => "b", "@S3_URL" => "c"}
|
193
|
-
assert_equal(expected_job_data_5, validate_storage_params(job_data_5))
|
206
|
+
assert_equal(expected_job_data_5, NeptuneHelper.validate_storage_params(job_data_5))
|
194
207
|
}
|
195
208
|
end
|
196
209
|
|
@@ -203,25 +216,40 @@ class TestNeptune < Test::Unit::TestCase
|
|
203
216
|
def test_compile_code
|
204
217
|
end
|
205
218
|
|
206
|
-
def
|
219
|
+
def test_run_job_with_errors
|
207
220
|
ssh_args = "boo!"
|
208
221
|
shadow_ip = "localhost?"
|
209
222
|
secret = "abcdefg"
|
210
223
|
|
211
224
|
job_data_1 = {"@type" => "input"}
|
212
|
-
assert_raises (
|
213
|
-
run_job(job_data_1, ssh_args, shadow_ip, secret
|
214
|
-
|
225
|
+
assert_raises (BadConfigurationException) {
|
226
|
+
NeptuneHelper.run_job(job_data_1, ssh_args, shadow_ip, secret)
|
227
|
+
}
|
228
|
+
|
229
|
+
@file.should_receive(:exists?).and_return(false)
|
230
|
+
flexmock(AppControllerClient).new_instances { |instance|
|
231
|
+
instance.should_receive(:put_input).and_return(true)
|
215
232
|
}
|
216
233
|
|
217
234
|
job_data_1 = {"@type" => "input", "@local" => "NON-EXISTANT"}
|
218
|
-
actual_1 = run_job(job_data_1, ssh_args, shadow_ip, secret
|
219
|
-
FakeAppControllerClient, FakeFileNeptuneTest)
|
235
|
+
actual_1 = NeptuneHelper.run_job(job_data_1, ssh_args, shadow_ip, secret)
|
220
236
|
assert_equal(:failure, actual_1[:result])
|
237
|
+
end
|
238
|
+
|
239
|
+
def test_run_job_no_errors
|
240
|
+
ssh_args = "boo!"
|
241
|
+
shadow_ip = "localhost?"
|
242
|
+
secret = "abcdefg"
|
243
|
+
|
244
|
+
flexmock(AppControllerClient).new_instances { |instance|
|
245
|
+
instance.should_receive(:put_input).and_return(true)
|
246
|
+
}
|
247
|
+
|
248
|
+
|
249
|
+
@file.should_receive(:exists?).and_return(true)
|
221
250
|
|
222
251
|
job_data_2 = {"@type" => "input", "@local" => "EXISTS"}
|
223
|
-
actual_2 = run_job(job_data_2, ssh_args, shadow_ip, secret
|
224
|
-
FakeAppControllerClient, FakeFileNeptuneTest)
|
252
|
+
actual_2 = NeptuneHelper.run_job(job_data_2, ssh_args, shadow_ip, secret)
|
225
253
|
assert_equal(:success, actual_2[:result])
|
226
254
|
|
227
255
|
# try an output job
|
@@ -234,4 +262,68 @@ class TestNeptune < Test::Unit::TestCase
|
|
234
262
|
|
235
263
|
# try a compute job
|
236
264
|
end
|
265
|
+
|
266
|
+
def test_babel_job_validation
|
267
|
+
input = "/boo/input.txt"
|
268
|
+
output = "/boo/baz.txt"
|
269
|
+
code = "/boo/code.go"
|
270
|
+
engine = "appscale-sqs"
|
271
|
+
all_engines = [engine]
|
272
|
+
|
273
|
+
@commonfunctions.should_receive(:get_from_yaml).and_return("127.0.0.1")
|
274
|
+
@commonfunctions.should_receive(:get_secret_key).and_return("secret")
|
275
|
+
|
276
|
+
flexmock(AppControllerClient).new_instances { |instance|
|
277
|
+
instance.should_receive(:start_neptune_job).and_return("babel job is now running")
|
278
|
+
instance.should_receive(:get_supported_babel_engines).and_return(all_engines)
|
279
|
+
instance.should_receive(:does_file_exist?).and_return(true, false, true)
|
280
|
+
}
|
281
|
+
|
282
|
+
# test cases where we don't give all the correct params
|
283
|
+
params1 = {:type => :babel}
|
284
|
+
assert_raises(BadConfigurationException) { neptune(params1) }
|
285
|
+
|
286
|
+
params2 = {:type => :babel, :output => output}
|
287
|
+
assert_raises(BadConfigurationException) { neptune(params2) }
|
288
|
+
|
289
|
+
params3 = {:type => :babel, :output => output, :code => code}
|
290
|
+
assert_raises(BadConfigurationException) { neptune(params3) }
|
291
|
+
|
292
|
+
# test a case where we do give all the correct params
|
293
|
+
|
294
|
+
params = {:type => :babel,
|
295
|
+
:output => output,
|
296
|
+
:code => code,
|
297
|
+
:engine => engine,
|
298
|
+
:argv => [input]}
|
299
|
+
result = neptune(params)
|
300
|
+
assert_equal(:success, result[:result])
|
301
|
+
end
|
302
|
+
|
303
|
+
def test_babel_where_remote_files_dont_exist
|
304
|
+
output = "/boo/baz.txt"
|
305
|
+
code = "/boo/code.go"
|
306
|
+
engine = "appscale-sqs"
|
307
|
+
all_engines = [engine]
|
308
|
+
|
309
|
+
@commonfunctions.should_receive(:get_from_yaml).and_return("127.0.0.1")
|
310
|
+
@commonfunctions.should_receive(:get_secret_key).and_return("secret")
|
311
|
+
|
312
|
+
flexmock(AppControllerClient).new_instances { |instance|
|
313
|
+
instance.should_receive(:start_neptune_job).and_return("babel job is now running")
|
314
|
+
instance.should_receive(:get_supported_babel_engines).and_return(all_engines)
|
315
|
+
instance.should_receive(:does_file_exist?).and_return(false)
|
316
|
+
}
|
317
|
+
|
318
|
+
params = {:type => :babel,
|
319
|
+
:output => output,
|
320
|
+
:code => code,
|
321
|
+
:engine => engine}
|
322
|
+
assert_raises(FileNotFoundException) { neptune(params) }
|
323
|
+
|
324
|
+
end
|
325
|
+
|
326
|
+
def test_babel_engine_validation
|
327
|
+
# TODO(cgb): test a case where we name an unsupported engine - it should fail
|
328
|
+
end
|
237
329
|
end
|