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.
@@ -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(SystemExit) {
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(SystemExit) {
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(SystemExit) {
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(SystemExit) { @client.start_neptune_job(@job_data_err) }
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(SystemExit) { @client.put_input(@job_data_err) }
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(SystemExit) { @client.get_output(@job_data_err) }
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(SystemExit) { @client.get_acl(@job_data_err) }
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(SystemExit) { @client.set_acl(@job_data_err) }
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(SystemExit) { @client.compile_code(@job_data_err) }
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
- def self.scp_file(a, b, c, d, e)
15
- end
16
- end
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
- class FakeFile
19
- @@exists_checks_done = 0
17
+ @file = flexmock(File)
18
+ @file.should_receive(:expand_path).and_return("")
20
19
 
21
- def self.expand_path(path)
22
- return path
23
- end
20
+ @fileutils = flexmock(FileUtils)
21
+ @fileutils.should_receive(:rm_f).and_return()
24
22
 
25
- def self.exists?(name)
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
- def self.open(name, mode=nil)
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
- module FakeFileUtils
52
- def self.rm_f(name)
53
- # Do nothing - faking out File means we don't have extra files to clean up
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
- module FakeKernel
58
- def `(command)
59
- # Do nothing - we don't need the side-effects from exec'ing a command
32
+ assert_nothing_raised(Exception) {
33
+ CommonFunctions.scp_to_shadow("", "", "", "")
34
+ }
60
35
  end
61
36
 
62
- #def sleep(time)
63
- # Do nothing - we don't actually need to sleep the current thread
64
- #end
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
- module FakeYAML
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
- class TestCommonFunctions < Test::Unit::TestCase
80
- def test_scp_to_shadow
81
- assert_nothing_raised(Exception) {
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 test_get_secret_key
90
- assert_equal(SECRET, CommonFunctions.get_secret_key("OK", required=true,
91
- FakeFile, FakeYAML))
50
+ def test_get_secret_key_wrong_tag
51
+ assert_raise(BadConfigurationException) {
52
+ CommonFunctions.get_secret_key("", required=true)
53
+ }
92
54
 
93
- assert_raise(SystemExit) { CommonFunctions.get_secret_key("BAD-TAG",
94
- required=true, FakeFile, FakeYAML) }
55
+ @file.should_receive(:exists?).and_return(true)
95
56
 
96
- assert_raise(SystemExit) { CommonFunctions.get_secret_key("FAIL",
97
- required=true, FakeFile, FakeYAML) }
98
- assert_nil(CommonFunctions.get_secret_key("FAIL", required=false, FakeFile,
99
- FakeYAML))
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
- assert_raise(SystemExit) {
102
- CommonFunctions.get_secret_key("NOT-EXISTANT", required=true, FakeFile,
103
- FakeYAML)
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
@@ -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
- # Since all the methods we're faking take the same arguments and have
13
- # the same semantics (return true or abort), just cover it all in one place.
14
- def method_missing(id, *args, &block)
15
- method_names = ["get_output", "get_acl", "put_input", "set_acl"] +
16
- ["start_neptune_job"]
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
- class FakeFileNeptuneTest
26
- def self.expand_path(path)
27
- return path
28
- end
15
+ @file = flexmock(File)
16
+ @file.should_receive(:expand_path).and_return("")
29
17
 
30
- def self.exists?(file)
31
- if file.include?("EXISTS")
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
- module FakeKernel
40
- def `(command)
41
- end
42
- end
21
+ @kernel = flexmock(Kernel)
22
+ @kernel.should_receive(:puts).and_return()
43
23
 
44
- module FakeCommonFunctions
45
- def self.scp_to_shadow(a, b, c, d=nil)
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(SystemExit) { do_preprocessing(job_data_1) }
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(SystemExit) { do_preprocessing(job_data_2) }
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 test_preprocess_erlang
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(SystemExit) {
67
- preprocess_erlang(job_data_1, FakeFileNeptuneTest, FakeCommonFunctions)
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(SystemExit) {
73
- preprocess_erlang(job_data_2, FakeFileNeptuneTest, FakeCommonFunctions)
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(SystemExit) {
79
- preprocess_erlang(job_data_3, FakeFileNeptuneTest, FakeCommonFunctions)
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(SystemExit) { preprocess_mpi(job_data_1) }
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(SystemExit) { preprocess_mpi(job_data_2) }
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(SystemExit) { preprocess_mpi(job_data_4) }
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(SystemExit) { preprocess_mpi(job_data_7) }
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(SystemExit) { preprocess_ssa(job_data_1) }
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(SystemExit) { preprocess_ssa(job_data_4) }
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(SystemExit) { get_job_data(params_1) }
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(SystemExit) { get_job_data(params_2) }
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(SystemExit) { validate_storage_params(job_data_2) }
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(SystemExit) { validate_storage_params(job_data_3) }
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 test_run_job
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 (SystemExit) {
213
- run_job(job_data_1, ssh_args, shadow_ip, secret,
214
- FakeAppControllerClient, FakeFileNeptuneTest)
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