neptune 0.1.4 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|