osc_machete_rails 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +76 -0
- data/LICENSE.txt +22 -0
- data/README.md +14 -0
- data/Rakefile +34 -0
- data/app/assets/javascripts/osc_machete_rails/application.js +13 -0
- data/app/assets/stylesheets/osc_machete_rails/application.css +13 -0
- data/app/controllers/osc_machete_rails/application_controller.rb +4 -0
- data/app/helpers/osc_machete_rails/application_helper.rb +4 -0
- data/app/views/layouts/osc_machete_rails/application.html.erb +14 -0
- data/config/routes.rb +2 -0
- data/lib/generators/active_record/job_model_generator.rb +13 -0
- data/lib/generators/active_record/orm_helpers.rb +6 -0
- data/lib/generators/active_record/templates/job_model.rb +17 -0
- data/lib/generators/active_record/templates/migration.rb +19 -0
- data/lib/generators/active_record/templates/module.rb +7 -0
- data/lib/generators/active_record/templates/workflow_model.rb +34 -0
- data/lib/generators/active_record/workflow_model_generator.rb +30 -0
- data/lib/generators/osc_machete_rails/USAGE +36 -0
- data/lib/generators/osc_machete_rails/erb/erb_generator.rb +5 -0
- data/lib/generators/osc_machete_rails/erb/templates/_form.html.erb +21 -0
- data/lib/generators/osc_machete_rails/erb/templates/edit.html.erb +5 -0
- data/lib/generators/osc_machete_rails/erb/templates/index.html.erb +41 -0
- data/lib/generators/osc_machete_rails/erb/templates/new.html.erb +5 -0
- data/lib/generators/osc_machete_rails/erb/templates/show.html.erb +13 -0
- data/lib/generators/osc_machete_rails/job_helpers.rb +10 -0
- data/lib/generators/osc_machete_rails/job_model/USAGE +28 -0
- data/lib/generators/osc_machete_rails/job_model/job_model_generator.rb +13 -0
- data/lib/generators/osc_machete_rails/resource_route/USAGE +3 -0
- data/lib/generators/osc_machete_rails/resource_route/resource_route_generator.rb +57 -0
- data/lib/generators/osc_machete_rails/scaffold_controller/USAGE +17 -0
- data/lib/generators/osc_machete_rails/scaffold_controller/scaffold_controller_generator.rb +24 -0
- data/lib/generators/osc_machete_rails/scaffold_controller/templates/controller.rb +120 -0
- data/lib/generators/osc_machete_rails/scaffold_generator.rb +35 -0
- data/lib/generators/osc_machete_rails/workflow_model/USAGE +38 -0
- data/lib/generators/osc_machete_rails/workflow_model/workflow_model_generator.rb +12 -0
- data/lib/generators/osc_machete_rails/workflow_template/USAGE +19 -0
- data/lib/generators/osc_machete_rails/workflow_template/templates/main.sh.mustache +18 -0
- data/lib/generators/osc_machete_rails/workflow_template/workflow_template_generator.rb +9 -0
- data/lib/osc_machete_rails/engine.rb +24 -0
- data/lib/osc_machete_rails/helper.rb +25 -0
- data/lib/osc_machete_rails/statusable.rb +199 -0
- data/lib/osc_machete_rails/version.rb +3 -0
- data/lib/osc_machete_rails/workflow.rb +249 -0
- data/lib/osc_machete_rails.rb +12 -0
- data/lib/tasks/osc_machete_rails_tasks.rake +4 -0
- data/test/dummy/README.rdoc +28 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/javascripts/application.js +13 -0
- data/test/dummy/app/assets/javascripts/simulations.js +2 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/assets/stylesheets/simulations.css +4 -0
- data/test/dummy/app/controllers/application_controller.rb +5 -0
- data/test/dummy/app/controllers/simulations_controller.rb +103 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/helpers/simulations_helper.rb +2 -0
- data/test/dummy/app/models/simulation.rb +26 -0
- data/test/dummy/app/models/simulation_job.rb +15 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/app/views/simulations/_form.html.erb +15 -0
- data/test/dummy/app/views/simulations/edit.html.erb +5 -0
- data/test/dummy/app/views/simulations/index.html.erb +35 -0
- data/test/dummy/app/views/simulations/new.html.erb +5 -0
- data/test/dummy/app/views/simulations/show.html.erb +16 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/config/application.rb +23 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +29 -0
- data/test/dummy/config/environments/production.rb +80 -0
- data/test/dummy/config/environments/test.rb +36 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +12 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +11 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/migrate/20151230193910_create_simulations.rb +11 -0
- data/test/dummy/db/migrate/20151230193911_create_simulation_jobs.rb +15 -0
- data/test/dummy/db/schema.rb +38 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/jobs/simulation/main.sh.mustache +17 -0
- data/test/dummy/log/development.log +0 -0
- data/test/dummy/log/test.log +31198 -0
- data/test/dummy/public/404.html +58 -0
- data/test/dummy/public/422.html +58 -0
- data/test/dummy/public/500.html +57 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/0ff4cb4a6c217771a1336b307c51cf4e +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/57261b7c75c19be33229517e39e47528 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/9e1e594361ba2561e5f6011db99503bb +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/dc292ec300d07016ebcc2de4806208c3 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/test/integration/error_handling_test.rb +166 -0
- data/test/integration/statusable_update_status_test.rb +47 -0
- data/test/models/simulation_test.rb +4 -0
- data/test/osc_machete_rails_test.rb +7 -0
- data/test/test_helper.rb +19 -0
- data/test/unit/statusable_test.rb +124 -0
- metadata +320 -0
@@ -0,0 +1,58 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>The page you were looking for doesn't exist (404)</title>
|
5
|
+
<style>
|
6
|
+
body {
|
7
|
+
background-color: #EFEFEF;
|
8
|
+
color: #2E2F30;
|
9
|
+
text-align: center;
|
10
|
+
font-family: arial, sans-serif;
|
11
|
+
}
|
12
|
+
|
13
|
+
div.dialog {
|
14
|
+
width: 25em;
|
15
|
+
margin: 4em auto 0 auto;
|
16
|
+
border: 1px solid #CCC;
|
17
|
+
border-right-color: #999;
|
18
|
+
border-left-color: #999;
|
19
|
+
border-bottom-color: #BBB;
|
20
|
+
border-top: #B00100 solid 4px;
|
21
|
+
border-top-left-radius: 9px;
|
22
|
+
border-top-right-radius: 9px;
|
23
|
+
background-color: white;
|
24
|
+
padding: 7px 4em 0 4em;
|
25
|
+
}
|
26
|
+
|
27
|
+
h1 {
|
28
|
+
font-size: 100%;
|
29
|
+
color: #730E15;
|
30
|
+
line-height: 1.5em;
|
31
|
+
}
|
32
|
+
|
33
|
+
body > p {
|
34
|
+
width: 33em;
|
35
|
+
margin: 0 auto 1em;
|
36
|
+
padding: 1em 0;
|
37
|
+
background-color: #F7F7F7;
|
38
|
+
border: 1px solid #CCC;
|
39
|
+
border-right-color: #999;
|
40
|
+
border-bottom-color: #999;
|
41
|
+
border-bottom-left-radius: 4px;
|
42
|
+
border-bottom-right-radius: 4px;
|
43
|
+
border-top-color: #DADADA;
|
44
|
+
color: #666;
|
45
|
+
box-shadow:0 3px 8px rgba(50, 50, 50, 0.17);
|
46
|
+
}
|
47
|
+
</style>
|
48
|
+
</head>
|
49
|
+
|
50
|
+
<body>
|
51
|
+
<!-- This file lives in public/404.html -->
|
52
|
+
<div class="dialog">
|
53
|
+
<h1>The page you were looking for doesn't exist.</h1>
|
54
|
+
<p>You may have mistyped the address or the page may have moved.</p>
|
55
|
+
</div>
|
56
|
+
<p>If you are the application owner check the logs for more information.</p>
|
57
|
+
</body>
|
58
|
+
</html>
|
@@ -0,0 +1,58 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>The change you wanted was rejected (422)</title>
|
5
|
+
<style>
|
6
|
+
body {
|
7
|
+
background-color: #EFEFEF;
|
8
|
+
color: #2E2F30;
|
9
|
+
text-align: center;
|
10
|
+
font-family: arial, sans-serif;
|
11
|
+
}
|
12
|
+
|
13
|
+
div.dialog {
|
14
|
+
width: 25em;
|
15
|
+
margin: 4em auto 0 auto;
|
16
|
+
border: 1px solid #CCC;
|
17
|
+
border-right-color: #999;
|
18
|
+
border-left-color: #999;
|
19
|
+
border-bottom-color: #BBB;
|
20
|
+
border-top: #B00100 solid 4px;
|
21
|
+
border-top-left-radius: 9px;
|
22
|
+
border-top-right-radius: 9px;
|
23
|
+
background-color: white;
|
24
|
+
padding: 7px 4em 0 4em;
|
25
|
+
}
|
26
|
+
|
27
|
+
h1 {
|
28
|
+
font-size: 100%;
|
29
|
+
color: #730E15;
|
30
|
+
line-height: 1.5em;
|
31
|
+
}
|
32
|
+
|
33
|
+
body > p {
|
34
|
+
width: 33em;
|
35
|
+
margin: 0 auto 1em;
|
36
|
+
padding: 1em 0;
|
37
|
+
background-color: #F7F7F7;
|
38
|
+
border: 1px solid #CCC;
|
39
|
+
border-right-color: #999;
|
40
|
+
border-bottom-color: #999;
|
41
|
+
border-bottom-left-radius: 4px;
|
42
|
+
border-bottom-right-radius: 4px;
|
43
|
+
border-top-color: #DADADA;
|
44
|
+
color: #666;
|
45
|
+
box-shadow:0 3px 8px rgba(50, 50, 50, 0.17);
|
46
|
+
}
|
47
|
+
</style>
|
48
|
+
</head>
|
49
|
+
|
50
|
+
<body>
|
51
|
+
<!-- This file lives in public/422.html -->
|
52
|
+
<div class="dialog">
|
53
|
+
<h1>The change you wanted was rejected.</h1>
|
54
|
+
<p>Maybe you tried to change something you didn't have access to.</p>
|
55
|
+
</div>
|
56
|
+
<p>If you are the application owner check the logs for more information.</p>
|
57
|
+
</body>
|
58
|
+
</html>
|
@@ -0,0 +1,57 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>We're sorry, but something went wrong (500)</title>
|
5
|
+
<style>
|
6
|
+
body {
|
7
|
+
background-color: #EFEFEF;
|
8
|
+
color: #2E2F30;
|
9
|
+
text-align: center;
|
10
|
+
font-family: arial, sans-serif;
|
11
|
+
}
|
12
|
+
|
13
|
+
div.dialog {
|
14
|
+
width: 25em;
|
15
|
+
margin: 4em auto 0 auto;
|
16
|
+
border: 1px solid #CCC;
|
17
|
+
border-right-color: #999;
|
18
|
+
border-left-color: #999;
|
19
|
+
border-bottom-color: #BBB;
|
20
|
+
border-top: #B00100 solid 4px;
|
21
|
+
border-top-left-radius: 9px;
|
22
|
+
border-top-right-radius: 9px;
|
23
|
+
background-color: white;
|
24
|
+
padding: 7px 4em 0 4em;
|
25
|
+
}
|
26
|
+
|
27
|
+
h1 {
|
28
|
+
font-size: 100%;
|
29
|
+
color: #730E15;
|
30
|
+
line-height: 1.5em;
|
31
|
+
}
|
32
|
+
|
33
|
+
body > p {
|
34
|
+
width: 33em;
|
35
|
+
margin: 0 auto 1em;
|
36
|
+
padding: 1em 0;
|
37
|
+
background-color: #F7F7F7;
|
38
|
+
border: 1px solid #CCC;
|
39
|
+
border-right-color: #999;
|
40
|
+
border-bottom-color: #999;
|
41
|
+
border-bottom-left-radius: 4px;
|
42
|
+
border-bottom-right-radius: 4px;
|
43
|
+
border-top-color: #DADADA;
|
44
|
+
color: #666;
|
45
|
+
box-shadow:0 3px 8px rgba(50, 50, 50, 0.17);
|
46
|
+
}
|
47
|
+
</style>
|
48
|
+
</head>
|
49
|
+
|
50
|
+
<body>
|
51
|
+
<!-- This file lives in public/500.html -->
|
52
|
+
<div class="dialog">
|
53
|
+
<h1>We're sorry, but something went wrong.</h1>
|
54
|
+
</div>
|
55
|
+
<p>If you are the application owner check the logs for more information.</p>
|
56
|
+
</body>
|
57
|
+
</html>
|
File without changes
|
@@ -0,0 +1,166 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ErrorHandlingTest < ActionDispatch::IntegrationTest
|
4
|
+
|
5
|
+
# these tests are for
|
6
|
+
|
7
|
+
def setup
|
8
|
+
setup_torquehelper
|
9
|
+
|
10
|
+
# FIXME: better to create simulations from doing a request to post a new sim
|
11
|
+
@sim = Simulation.create
|
12
|
+
@tmpdir = Dir.mktmpdir
|
13
|
+
@empty_template = Pathname.new(@tmpdir + "/template")
|
14
|
+
FileUtils.mkdir(@empty_template.to_s)
|
15
|
+
@empty_template = @empty_template.realpath
|
16
|
+
|
17
|
+
# so Workflow#ood_dataroot is set
|
18
|
+
ENV['OOD_DATAROOT'] = @tmpdir
|
19
|
+
end
|
20
|
+
|
21
|
+
def setup_torquehelper
|
22
|
+
# defaults
|
23
|
+
OSC::Machete::TorqueHelper.any_instance.unstub(:qstat)
|
24
|
+
OSC::Machete::TorqueHelper.any_instance.unstub(:qdel)
|
25
|
+
OSC::Machete::TorqueHelper.any_instance.unstub(:qsub)
|
26
|
+
|
27
|
+
# use subclasses of PBS::Error
|
28
|
+
OSC::Machete::TorqueHelper.any_instance.stubs(:qstat).raises(PBS::SystemError, "The system is down!")
|
29
|
+
OSC::Machete::TorqueHelper.any_instance.stubs(:qdel).raises(PBS::BadhostError, "The system is down!")
|
30
|
+
OSC::Machete::TorqueHelper.any_instance.stubs(:qsub).raises(PBS::BadatvalError, "The system is down!")
|
31
|
+
end
|
32
|
+
|
33
|
+
def teardown
|
34
|
+
@sim.delete
|
35
|
+
FileUtils.rm_rf @tmpdir
|
36
|
+
end
|
37
|
+
|
38
|
+
def simulations_dir_empty?
|
39
|
+
Dir[@tmpdir+'/*'].empty? || Dir[@tmpdir+'/simulations/*'].empty?
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_handle_missing_script_error_on_submit
|
43
|
+
# stub to an empty template to trigger ScriptMissingError
|
44
|
+
Simulation.any_instance.stubs(:staging_template_dir).returns(@empty_template)
|
45
|
+
|
46
|
+
# sanity check
|
47
|
+
assert_equal 1, Simulation.count, "Sanity check failed"
|
48
|
+
assert simulations_dir_empty?, "Sanity check failed"
|
49
|
+
assert @empty_template.directory?, "Sanity check failed"
|
50
|
+
|
51
|
+
# now we should be able to try to submit the simulation, that needs main.sh but doesn't have it
|
52
|
+
put "/simulations/#{@sim.id}/submit"
|
53
|
+
|
54
|
+
assert_response 500
|
55
|
+
|
56
|
+
# verify an error message was attached to the simulation object
|
57
|
+
assert assigns(:simulation).errors.to_a.any?
|
58
|
+
assert assigns(:simulation).errors.to_a.first =~ /ScriptMissingError/, "Should have thrown ScriptMissingError"
|
59
|
+
assert simulations_dir_empty?, 'If submitting a simulation fails, the staged directory should be deleted.'
|
60
|
+
|
61
|
+
Simulation.any_instance.unstub(:staging_template_dir)
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_handle_pbs_error_on_submit
|
65
|
+
# sanity check
|
66
|
+
assert_equal 1, Simulation.count, "Sanity check failed"
|
67
|
+
assert simulations_dir_empty?, "Sanity check failed"
|
68
|
+
|
69
|
+
# now we should be able to try to submit a simulation
|
70
|
+
put "/simulations/#{@sim.id}/submit"
|
71
|
+
|
72
|
+
assert_response 500
|
73
|
+
|
74
|
+
# verify an error message was attached to the simulation object
|
75
|
+
assert assigns(:simulation).errors.to_a.any?
|
76
|
+
assert assigns(:simulation).errors.to_a.first =~ /PBS::Error/, "Should have thrown PBS::Error"
|
77
|
+
assert simulations_dir_empty?, 'If submitting a simulation fails, the staged directory should be deleted.'
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_handle_qstat_error_on_submit
|
81
|
+
OSC::Machete::TorqueHelper.any_instance.stubs(:qsub).returns("123456.oakley.osc.edu")
|
82
|
+
|
83
|
+
put "/simulations/#{@sim.id}/submit"
|
84
|
+
|
85
|
+
assert_response :found
|
86
|
+
|
87
|
+
# submission succeeded, but qdel failed!
|
88
|
+
assert Simulation.find(@sim.id).status.queued?
|
89
|
+
assert Simulation.find(@sim.id).simulation_jobs.count == 1
|
90
|
+
|
91
|
+
# reset
|
92
|
+
setup_torquehelper
|
93
|
+
end
|
94
|
+
|
95
|
+
|
96
|
+
def test_update_status_handles_qstat_error
|
97
|
+
@s1 = SimulationJob.create status: OSC::Machete::Status.queued, pbsid: "1"
|
98
|
+
@s2 = SimulationJob.create status: OSC::Machete::Status.queued, pbsid: "2"
|
99
|
+
@s3 = SimulationJob.create status: OSC::Machete::Status.queued, pbsid: "3"
|
100
|
+
|
101
|
+
# new
|
102
|
+
OSC::Machete::TorqueHelper.any_instance.stubs(:qstat).with("1", any_parameters).returns(OSC::Machete::Status.running)
|
103
|
+
OSC::Machete::TorqueHelper.any_instance.stubs(:qstat).with("2", any_parameters).raises(PBS::Error, "The system is down!")
|
104
|
+
OSC::Machete::TorqueHelper.any_instance.stubs(:qstat).with("3", any_parameters).returns(OSC::Machete::Status.passed)
|
105
|
+
|
106
|
+
get "/simulations"
|
107
|
+
|
108
|
+
# @s2 is queued and qstat will throw an error so it should just stay queued
|
109
|
+
# the others should be updated
|
110
|
+
assert_equal OSC::Machete::Status.running, SimulationJob.find(@s1.id).status
|
111
|
+
assert_equal OSC::Machete::Status.queued, SimulationJob.find(@s2.id).status
|
112
|
+
assert_equal OSC::Machete::Status.passed, SimulationJob.find(@s3.id).status
|
113
|
+
|
114
|
+
@s1.delete
|
115
|
+
@s2.delete
|
116
|
+
@s3.delete
|
117
|
+
|
118
|
+
# reset
|
119
|
+
setup_torquehelper
|
120
|
+
end
|
121
|
+
|
122
|
+
|
123
|
+
def test_delete_running_simulation_fails
|
124
|
+
OSC::Machete::TorqueHelper.any_instance.stubs(:qsub).returns("123456.oakley.osc.edu")
|
125
|
+
OSC::Machete::TorqueHelper.any_instance.stubs(:qstat).returns(OSC::Machete::Status.running)
|
126
|
+
|
127
|
+
put "/simulations/#{@sim.id}/submit"
|
128
|
+
|
129
|
+
assert_response :found
|
130
|
+
|
131
|
+
# verify we its running now
|
132
|
+
assert Simulation.find(@sim.id).status.running?
|
133
|
+
assert Simulation.find(@sim.id).simulation_jobs.count == 1
|
134
|
+
|
135
|
+
@job = @sim.simulation_jobs.first
|
136
|
+
|
137
|
+
# delete a running simulation
|
138
|
+
delete "/simulations/#{@sim.id}"
|
139
|
+
|
140
|
+
# delete threw error, so nothing should have happened
|
141
|
+
assert SimulationJob.find(@job.id).status.running?
|
142
|
+
assert Simulation.find(@sim.id).status.running?
|
143
|
+
assert Simulation.find(@sim.id).simulation_jobs.count == 1
|
144
|
+
|
145
|
+
assert_response 500
|
146
|
+
|
147
|
+
# verify an error message was attached to the simulation object
|
148
|
+
assert assigns(:simulation).errors.to_a.any?
|
149
|
+
assert assigns(:simulation).errors.to_a.first =~ /PBS::Error/, "Should have thrown PBS::Error"
|
150
|
+
|
151
|
+
OSC::Machete::TorqueHelper.any_instance.stubs(:qdel).returns(nil)
|
152
|
+
|
153
|
+
# delete simulation now that "the system is fixed"
|
154
|
+
delete "/simulations/#{@sim.id}"
|
155
|
+
|
156
|
+
# delete threw error, so nothing should have happened
|
157
|
+
assert ! SimulationJob.where(id: @job.id).any?
|
158
|
+
assert ! Simulation.where(id: @sim.id).any?
|
159
|
+
|
160
|
+
assert_response :found
|
161
|
+
|
162
|
+
# reset
|
163
|
+
setup_torquehelper
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class StatusableUpdateStatusTest < ActionDispatch::IntegrationTest
|
4
|
+
fixtures :all
|
5
|
+
|
6
|
+
def setup
|
7
|
+
# FIXME: better to create simulations from doing a request to post a new sim
|
8
|
+
@sims = []
|
9
|
+
@sims << SimulationJob.create(status: OSC::Machete::Status.passed, pbsid: "123")
|
10
|
+
@sims << SimulationJob.create(status: OSC::Machete::Status.not_submitted, pbsid: "124")
|
11
|
+
@sims << SimulationJob.create(status: OSC::Machete::Status.queued, pbsid: "125")
|
12
|
+
@sims << SimulationJob.create(status: OSC::Machete::Status.running, pbsid: "126")
|
13
|
+
@sims << SimulationJob.create(status: OSC::Machete::Status.queued, pbsid: "127")
|
14
|
+
end
|
15
|
+
|
16
|
+
def teardown
|
17
|
+
# delete will avoid calling the destroy callbacks like "stop" i.e. qdel
|
18
|
+
@sims.each(&:delete)
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_update_models_on_index_request
|
22
|
+
# 1. setup database and torque helper with jobs so that two jobs that are
|
23
|
+
# cached as queued and running are actually running and passed
|
24
|
+
OSC::Machete::TorqueHelper.any_instance.stubs(:qstat).returns(OSC::Machete::Status.passed)
|
25
|
+
|
26
|
+
# if a test below suddenly returns "Passed" instead of running it might be
|
27
|
+
# because the signature of qstat or the arguments Job#status is passing to
|
28
|
+
# these by default are different.
|
29
|
+
OSC::Machete::TorqueHelper.any_instance.stubs(:qstat).with("125", any_parameters).returns(OSC::Machete::Status.running)
|
30
|
+
OSC::Machete::TorqueHelper.any_instance.stubs(:qstat).with("127", any_parameters).returns(OSC::Machete::Status.queued)
|
31
|
+
|
32
|
+
# FIXME: move to a controller test?
|
33
|
+
assert_equal @sims.length, SimulationJob.count, "Test database is not cleaned up after each test is run"
|
34
|
+
|
35
|
+
# 2. when doing a get request, the active jobs should be updated
|
36
|
+
get "/simulations"
|
37
|
+
assert_response :success
|
38
|
+
|
39
|
+
# 3. we verify the modifications to the active jobs took place
|
40
|
+
assert_equal OSC::Machete::Status.passed, SimulationJob.where(pbsid: "123").first.status
|
41
|
+
assert_equal OSC::Machete::Status.not_submitted, SimulationJob.where(pbsid: "124").first.status
|
42
|
+
assert_equal OSC::Machete::Status.running, SimulationJob.where(pbsid: "125").first.status
|
43
|
+
assert_equal OSC::Machete::Status.passed, SimulationJob.where(pbsid: "126").first.status
|
44
|
+
assert_equal OSC::Machete::Status.queued, SimulationJob.where(pbsid: "127").first.status
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# Configure Rails Environment
|
2
|
+
ENV["RAILS_ENV"] = "test"
|
3
|
+
ENV["RAILS_DATAROOT"] = "/dev/null"
|
4
|
+
|
5
|
+
require File.expand_path("../dummy/config/environment.rb", __FILE__)
|
6
|
+
require "rails/test_help"
|
7
|
+
|
8
|
+
# dependencies that dummy app depends on
|
9
|
+
require "bootstrap_form"
|
10
|
+
|
11
|
+
Rails.backtrace_cleaner.remove_silencers!
|
12
|
+
|
13
|
+
# Load support files
|
14
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
15
|
+
|
16
|
+
# Load fixtures from the engine
|
17
|
+
if ActiveSupport::TestCase.method_defined?(:fixture_path=)
|
18
|
+
ActiveSupport::TestCase.fixture_path = File.expand_path("../fixtures", __FILE__)
|
19
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'osc/machete'
|
3
|
+
|
4
|
+
class StatusableTest < Minitest::Unit::TestCase
|
5
|
+
# FIXME: the problem here: we are extending, not including, so
|
6
|
+
# Statusable#included never called
|
7
|
+
#
|
8
|
+
# Change the tests to do this appropriately!
|
9
|
+
# Or just use a dummy object SimulationJob
|
10
|
+
def setup
|
11
|
+
@job = SimulationJob.create(pbsid: "123456.oak-batch.osc.edu", job_path: "/path/to/tmp", script_name: "test.sh")
|
12
|
+
@job_without_script_name = SimulationJob.create(pbsid: "123456.oak-batch.osc.edu", job_path: "/path/to/tmp")
|
13
|
+
end
|
14
|
+
|
15
|
+
def teardown
|
16
|
+
@job.delete
|
17
|
+
@job_without_script_name.delete
|
18
|
+
end
|
19
|
+
|
20
|
+
# verify both of these calls work without crashing
|
21
|
+
def test_job_getter_works
|
22
|
+
assert_equal "test.sh", @job.job.script_name
|
23
|
+
assert_nil @job_without_script_name.job.script_name
|
24
|
+
end
|
25
|
+
|
26
|
+
# if calling status returns :Q for Queued, make sure this
|
27
|
+
def test_status_sym
|
28
|
+
@job.status = nil
|
29
|
+
assert ! @job.submitted?
|
30
|
+
assert @job.not_submitted?
|
31
|
+
|
32
|
+
@job.status = :Q
|
33
|
+
|
34
|
+
assert @job.submitted?
|
35
|
+
assert ! @job.completed?
|
36
|
+
assert @job.active?
|
37
|
+
assert_equal "Queued", @job.status.to_s
|
38
|
+
|
39
|
+
@job.status = :R
|
40
|
+
assert @job.active?
|
41
|
+
assert_equal "Running", @job.status.to_s
|
42
|
+
|
43
|
+
@job.status = :C
|
44
|
+
assert @job.completed?, "completed? should return true when status is C"
|
45
|
+
assert ! @job.failed?, "failed? should return false when status is not F"
|
46
|
+
|
47
|
+
@job.status = :F
|
48
|
+
assert @job.completed?, "completed? should return true when status is F"
|
49
|
+
assert ! @job.passed?, "passed? should return false when status is F"
|
50
|
+
assert @job.failed?, "failed? should return true when status is F"
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_status_str
|
54
|
+
@job.status = "Q"
|
55
|
+
|
56
|
+
assert @job.submitted?
|
57
|
+
assert ! @job.completed?
|
58
|
+
assert @job.active?
|
59
|
+
assert_equal "Queued", @job.status.to_s
|
60
|
+
|
61
|
+
@job.status = "R"
|
62
|
+
assert @job.active?
|
63
|
+
assert_equal "Running", @job.status.to_s
|
64
|
+
|
65
|
+
@job.status = "C"
|
66
|
+
assert @job.completed?, "completed? should return true when status is C"
|
67
|
+
assert ! @job.failed?, "failed? should return false when status is not F"
|
68
|
+
|
69
|
+
@job.status = "F"
|
70
|
+
assert @job.completed?, "completed? should return true when status is F"
|
71
|
+
assert ! @job.passed?, "passed? should return false when status is F"
|
72
|
+
assert @job.failed?, "failed? should return true when status is F"
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
def test_results_valid_hook_called
|
77
|
+
OSC::Machete::Job.any_instance.stubs(:status).returns(OSC::Machete::Status.passed)
|
78
|
+
@job.status = "R"
|
79
|
+
@job.expects(:"results_valid?").at_least_once
|
80
|
+
@job.update_status!
|
81
|
+
|
82
|
+
|
83
|
+
# sometimes, qstat returns "C": still call the hook!
|
84
|
+
assert_equal OSC::Machete::Status.passed, @job.job.status
|
85
|
+
|
86
|
+
@job.status = "R"
|
87
|
+
@job.expects(:"results_valid?").at_least_once
|
88
|
+
@job.update_status!
|
89
|
+
|
90
|
+
# but if the status is completed we don't want the hook to run again
|
91
|
+
@job.expects(:"results_valid?").never
|
92
|
+
@job.status = "C"
|
93
|
+
@job.update_status!
|
94
|
+
end
|
95
|
+
|
96
|
+
# if status is R but also saved record is also R we shouldn't save
|
97
|
+
def test_save_after_update_when_status_returns_symbol
|
98
|
+
OSC::Machete::Job.any_instance.stubs(:status).returns(OSC::Machete::Status.running)
|
99
|
+
assert OSC::Machete::Status.running, @job.job.status
|
100
|
+
|
101
|
+
@job.expects(:"save").never
|
102
|
+
@job.status = "R"
|
103
|
+
@job.update_status!
|
104
|
+
|
105
|
+
@job.expects(:"save").at_least_once
|
106
|
+
@job.status = "Q"
|
107
|
+
@job.update_status!
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_update_status_with_not_submitted_with_pbsid
|
111
|
+
OSC::Machete::Job.any_instance.stubs(:status).returns(OSC::Machete::Status.running)
|
112
|
+
@job.expects(:"save").at_least_once
|
113
|
+
@job.status = nil
|
114
|
+
@job.update_status!
|
115
|
+
end
|
116
|
+
|
117
|
+
def test_update_status_with_not_submitted_without_pbsid
|
118
|
+
OSC::Machete::Job.any_instance.stubs(:status).returns(OSC::Machete::Status.running)
|
119
|
+
@job.expects(:"save").never
|
120
|
+
@job.pbsid = nil
|
121
|
+
@job.status = nil
|
122
|
+
@job.update_status!
|
123
|
+
end
|
124
|
+
end
|