osc_machete_rails 1.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.
Files changed (113) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +76 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.md +14 -0
  5. data/Rakefile +34 -0
  6. data/app/assets/javascripts/osc_machete_rails/application.js +13 -0
  7. data/app/assets/stylesheets/osc_machete_rails/application.css +13 -0
  8. data/app/controllers/osc_machete_rails/application_controller.rb +4 -0
  9. data/app/helpers/osc_machete_rails/application_helper.rb +4 -0
  10. data/app/views/layouts/osc_machete_rails/application.html.erb +14 -0
  11. data/config/routes.rb +2 -0
  12. data/lib/generators/active_record/job_model_generator.rb +13 -0
  13. data/lib/generators/active_record/orm_helpers.rb +6 -0
  14. data/lib/generators/active_record/templates/job_model.rb +17 -0
  15. data/lib/generators/active_record/templates/migration.rb +19 -0
  16. data/lib/generators/active_record/templates/module.rb +7 -0
  17. data/lib/generators/active_record/templates/workflow_model.rb +34 -0
  18. data/lib/generators/active_record/workflow_model_generator.rb +30 -0
  19. data/lib/generators/osc_machete_rails/USAGE +36 -0
  20. data/lib/generators/osc_machete_rails/erb/erb_generator.rb +5 -0
  21. data/lib/generators/osc_machete_rails/erb/templates/_form.html.erb +21 -0
  22. data/lib/generators/osc_machete_rails/erb/templates/edit.html.erb +5 -0
  23. data/lib/generators/osc_machete_rails/erb/templates/index.html.erb +41 -0
  24. data/lib/generators/osc_machete_rails/erb/templates/new.html.erb +5 -0
  25. data/lib/generators/osc_machete_rails/erb/templates/show.html.erb +13 -0
  26. data/lib/generators/osc_machete_rails/job_helpers.rb +10 -0
  27. data/lib/generators/osc_machete_rails/job_model/USAGE +28 -0
  28. data/lib/generators/osc_machete_rails/job_model/job_model_generator.rb +13 -0
  29. data/lib/generators/osc_machete_rails/resource_route/USAGE +3 -0
  30. data/lib/generators/osc_machete_rails/resource_route/resource_route_generator.rb +57 -0
  31. data/lib/generators/osc_machete_rails/scaffold_controller/USAGE +17 -0
  32. data/lib/generators/osc_machete_rails/scaffold_controller/scaffold_controller_generator.rb +24 -0
  33. data/lib/generators/osc_machete_rails/scaffold_controller/templates/controller.rb +120 -0
  34. data/lib/generators/osc_machete_rails/scaffold_generator.rb +35 -0
  35. data/lib/generators/osc_machete_rails/workflow_model/USAGE +38 -0
  36. data/lib/generators/osc_machete_rails/workflow_model/workflow_model_generator.rb +12 -0
  37. data/lib/generators/osc_machete_rails/workflow_template/USAGE +19 -0
  38. data/lib/generators/osc_machete_rails/workflow_template/templates/main.sh.mustache +18 -0
  39. data/lib/generators/osc_machete_rails/workflow_template/workflow_template_generator.rb +9 -0
  40. data/lib/osc_machete_rails/engine.rb +24 -0
  41. data/lib/osc_machete_rails/helper.rb +25 -0
  42. data/lib/osc_machete_rails/statusable.rb +199 -0
  43. data/lib/osc_machete_rails/version.rb +3 -0
  44. data/lib/osc_machete_rails/workflow.rb +249 -0
  45. data/lib/osc_machete_rails.rb +12 -0
  46. data/lib/tasks/osc_machete_rails_tasks.rake +4 -0
  47. data/test/dummy/README.rdoc +28 -0
  48. data/test/dummy/Rakefile +6 -0
  49. data/test/dummy/app/assets/javascripts/application.js +13 -0
  50. data/test/dummy/app/assets/javascripts/simulations.js +2 -0
  51. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  52. data/test/dummy/app/assets/stylesheets/simulations.css +4 -0
  53. data/test/dummy/app/controllers/application_controller.rb +5 -0
  54. data/test/dummy/app/controllers/simulations_controller.rb +103 -0
  55. data/test/dummy/app/helpers/application_helper.rb +2 -0
  56. data/test/dummy/app/helpers/simulations_helper.rb +2 -0
  57. data/test/dummy/app/models/simulation.rb +26 -0
  58. data/test/dummy/app/models/simulation_job.rb +15 -0
  59. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  60. data/test/dummy/app/views/simulations/_form.html.erb +15 -0
  61. data/test/dummy/app/views/simulations/edit.html.erb +5 -0
  62. data/test/dummy/app/views/simulations/index.html.erb +35 -0
  63. data/test/dummy/app/views/simulations/new.html.erb +5 -0
  64. data/test/dummy/app/views/simulations/show.html.erb +16 -0
  65. data/test/dummy/bin/bundle +3 -0
  66. data/test/dummy/bin/rails +4 -0
  67. data/test/dummy/bin/rake +4 -0
  68. data/test/dummy/config/application.rb +23 -0
  69. data/test/dummy/config/boot.rb +5 -0
  70. data/test/dummy/config/database.yml +25 -0
  71. data/test/dummy/config/environment.rb +5 -0
  72. data/test/dummy/config/environments/development.rb +29 -0
  73. data/test/dummy/config/environments/production.rb +80 -0
  74. data/test/dummy/config/environments/test.rb +36 -0
  75. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  76. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  77. data/test/dummy/config/initializers/inflections.rb +16 -0
  78. data/test/dummy/config/initializers/mime_types.rb +5 -0
  79. data/test/dummy/config/initializers/secret_token.rb +12 -0
  80. data/test/dummy/config/initializers/session_store.rb +3 -0
  81. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  82. data/test/dummy/config/locales/en.yml +23 -0
  83. data/test/dummy/config/routes.rb +11 -0
  84. data/test/dummy/config.ru +4 -0
  85. data/test/dummy/db/development.sqlite3 +0 -0
  86. data/test/dummy/db/migrate/20151230193910_create_simulations.rb +11 -0
  87. data/test/dummy/db/migrate/20151230193911_create_simulation_jobs.rb +15 -0
  88. data/test/dummy/db/schema.rb +38 -0
  89. data/test/dummy/db/test.sqlite3 +0 -0
  90. data/test/dummy/jobs/simulation/main.sh.mustache +17 -0
  91. data/test/dummy/log/development.log +0 -0
  92. data/test/dummy/log/test.log +31198 -0
  93. data/test/dummy/public/404.html +58 -0
  94. data/test/dummy/public/422.html +58 -0
  95. data/test/dummy/public/500.html +57 -0
  96. data/test/dummy/public/favicon.ico +0 -0
  97. data/test/dummy/tmp/cache/assets/test/sprockets/0ff4cb4a6c217771a1336b307c51cf4e +0 -0
  98. data/test/dummy/tmp/cache/assets/test/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
  99. data/test/dummy/tmp/cache/assets/test/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
  100. data/test/dummy/tmp/cache/assets/test/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
  101. data/test/dummy/tmp/cache/assets/test/sprockets/57261b7c75c19be33229517e39e47528 +0 -0
  102. data/test/dummy/tmp/cache/assets/test/sprockets/9e1e594361ba2561e5f6011db99503bb +0 -0
  103. data/test/dummy/tmp/cache/assets/test/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
  104. data/test/dummy/tmp/cache/assets/test/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
  105. data/test/dummy/tmp/cache/assets/test/sprockets/dc292ec300d07016ebcc2de4806208c3 +0 -0
  106. data/test/dummy/tmp/cache/assets/test/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
  107. data/test/integration/error_handling_test.rb +166 -0
  108. data/test/integration/statusable_update_status_test.rb +47 -0
  109. data/test/models/simulation_test.rb +4 -0
  110. data/test/osc_machete_rails_test.rb +7 -0
  111. data/test/test_helper.rb +19 -0
  112. data/test/unit/statusable_test.rb +124 -0
  113. 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
+
@@ -0,0 +1,4 @@
1
+ require 'test_helper'
2
+
3
+ class SimulationTest < ActiveSupport::TestCase
4
+ end
@@ -0,0 +1,7 @@
1
+ require 'test_helper'
2
+
3
+ class OscMacheteRailsTest < ActiveSupport::TestCase
4
+ test "truth" do
5
+ assert_kind_of Module, OscMacheteRails
6
+ end
7
+ end
@@ -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