osc-machete 1.1.4 → 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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/CHANGELOG.md +51 -1
- data/lib/osc/machete/job.rb +1 -1
- data/lib/osc/machete/process.rb +3 -0
- data/lib/osc/machete/status.rb +50 -29
- data/lib/osc/machete/torque_helper.rb +48 -59
- data/lib/osc/machete/user.rb +3 -0
- data/lib/osc/machete/version.rb +1 -1
- data/osc-machete.gemspec +2 -1
- data/test/test_job_dir.rb +1 -1
- data/test/test_location.rb +19 -19
- data/test/test_torque_helper.rb +74 -29
- data/test/test_torque_helper_live.rb +12 -11
- metadata +7 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 02bb808f1fcf915c8b6c5cbe38b00e692e021b03
|
4
|
+
data.tar.gz: dbed1c7b521247a391709633bb67a8e87dd37d93
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 84d14aa284eeac069213601ccd58ef5e8ebbdcc533c20cc1b2c646f339bbcf25815c77093099f3e06ea44755f27b10808b14f8beda4d80a4585cb5a6795e6e7e
|
7
|
+
data.tar.gz: 67295194bd75c9cf59a6cdc077025e199051bb7144b8de17650cdb002ec095e9a2a199fb1786328a266ad584370ad1a0daa5825197db68cd9e34683c49fe714e
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -5,6 +5,52 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|
5
5
|
|
6
6
|
## [Unreleased]
|
7
7
|
|
8
|
+
## [1.2.0] - 2016-09-06
|
9
|
+
|
10
|
+
### Added
|
11
|
+
|
12
|
+
- TorqueHelper.default= so we can specify a different TorqueHelper
|
13
|
+
- TorqueHelper#pbs to get the PBS::Batch object for the given id, script, or host.
|
14
|
+
This lets us change the TorqueHelper instance used as a default with a
|
15
|
+
different TorqueHelper class or instance that has a different implementation
|
16
|
+
of TorqueHelper#pbs.
|
17
|
+
- (OSC specific) Owens cluster support
|
18
|
+
- (OSC specific) LIB and BIN for specifying torque lib locations
|
19
|
+
|
20
|
+
### Changed
|
21
|
+
|
22
|
+
- Depends on latest version of pbs ruby gem 2.0
|
23
|
+
- TorqueHelper.default returns the same instance every time (which is now
|
24
|
+
memoized) instead of creating a new instance
|
25
|
+
|
26
|
+
### Deprecated
|
27
|
+
|
28
|
+
- `OSC::Machete::User` - use `OodSupport::User` instead
|
29
|
+
- `OSC::Machete::Process` - use `OodSupport::Process` instead
|
30
|
+
|
31
|
+
### Fixed
|
32
|
+
|
33
|
+
- yardoc documentation for OSC::Machete::Status class methods
|
34
|
+
- deprecation warnings by using File.exist? instead of File.exists?
|
35
|
+
|
36
|
+
## [1.1.4] - 2016-08-17
|
37
|
+
|
38
|
+
### Added
|
39
|
+
|
40
|
+
- `Job#host` getter (which should have been there but was accidentally omitted)
|
41
|
+
|
42
|
+
## [1.1.3] - 2016-06-07
|
43
|
+
|
44
|
+
### Fixed
|
45
|
+
|
46
|
+
- README and gemspec docs update for rubygems.org release
|
47
|
+
|
48
|
+
## [1.1.2] - 2016-06-07
|
49
|
+
|
50
|
+
### Fixed
|
51
|
+
|
52
|
+
- Copyright in LICENSE.txt
|
53
|
+
|
8
54
|
## [1.1.1] - 2016-02-24
|
9
55
|
|
10
56
|
### Fixed
|
@@ -79,7 +125,11 @@ lib/osc/machete/torque_helper.rb _(still an internal class right now, not meant
|
|
79
125
|
|
80
126
|
Previous release of osc-machete
|
81
127
|
|
82
|
-
[Unreleased]: https://github.com/AweSim-OSC/osc-machete/compare/v1.
|
128
|
+
[Unreleased]: https://github.com/AweSim-OSC/osc-machete/compare/v1.2.0...master
|
129
|
+
[1.2.0]: https://github.com/AweSim-OSC/osc-machete/compare/v1.1.4...v1.2.0
|
130
|
+
[1.1.4]: https://github.com/AweSim-OSC/osc-machete/compare/v1.1.3...v1.1.4
|
131
|
+
[1.1.3]: https://github.com/AweSim-OSC/osc-machete/compare/v1.1.2...v1.1.3
|
132
|
+
[1.1.2]: https://github.com/AweSim-OSC/osc-machete/compare/v1.1.1...v1.1.2
|
83
133
|
[1.1.1]: https://github.com/AweSim-OSC/osc-machete/compare/v1.1.0...v1.1.1
|
84
134
|
[1.1.0]: https://github.com/AweSim-OSC/osc-machete/compare/v1.0.1...v1.1.0
|
85
135
|
[1.0.1]: https://github.com/AweSim-OSC/osc-machete/compare/v1.0.0...v1.0.1
|
data/lib/osc/machete/job.rb
CHANGED
@@ -205,7 +205,7 @@ class OSC::Machete::Job
|
|
205
205
|
# something if the script name is munged
|
206
206
|
|
207
207
|
# recursively delete the directory after killing the job
|
208
|
-
Pathname.new(path).rmtree if path && rmdir && File.
|
208
|
+
Pathname.new(path).rmtree if path && rmdir && File.exist?(path)
|
209
209
|
end
|
210
210
|
end
|
211
211
|
|
data/lib/osc/machete/process.rb
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
# Class that maintains the User and additional methods for the process.
|
2
2
|
# Helper methods provided use the Process module underneath.
|
3
3
|
#
|
4
|
+
# @deprecated Please use {http://www.rubydoc.info/gems/ood_support/OodSupport/Process OodSupport::Process} instead.
|
4
5
|
class OSC::Machete::Process
|
5
6
|
|
6
7
|
def initialize
|
7
8
|
@user = OSC::Machete::User.from_uid(Process.uid)
|
9
|
+
|
10
|
+
warn "[DEPRECATION] `OSC::Machete::Process` is deprecated. Please use `OodSupport::Process` instead (see ood_support gem)."
|
8
11
|
end
|
9
12
|
|
10
13
|
# The system name of the process user
|
data/lib/osc/machete/status.rb
CHANGED
@@ -55,27 +55,42 @@ class OSC::Machete::Status
|
|
55
55
|
end
|
56
56
|
|
57
57
|
|
58
|
-
#
|
59
|
-
#
|
60
|
-
|
61
|
-
#
|
62
|
-
|
63
|
-
#
|
64
|
-
|
65
|
-
#
|
66
|
-
|
67
|
-
#
|
68
|
-
|
69
|
-
# @return [Status]
|
70
|
-
def self.running() end
|
71
|
-
# @return [Status]
|
72
|
-
def self.queued() end
|
73
|
-
# @return [Status]
|
74
|
-
def self.held() end
|
75
|
-
# @return [Status]
|
76
|
-
def self.suspended() end
|
77
|
-
|
58
|
+
# NOTE: on yard documentation: to do something like what I do below,
|
59
|
+
# documenting a set of class methods, you must have the documentation block be
|
60
|
+
# inside the `class << self` block or else the last documented method will be
|
61
|
+
# ignored or hidden if newlines exist between each @!method block. If no
|
62
|
+
# newlines exist, like below, the entire block would have been ignored.
|
63
|
+
# Also, indenting the tags for the rest of the methods is required when
|
64
|
+
# omitting newlines, otherwise, each method includes all of the returns below
|
65
|
+
# it - so yard displays 6 return Status lines for the method.
|
66
|
+
#
|
67
|
+
# Why do we have no newlines here? So that "View source" on each of these
|
68
|
+
# class methods points to the block itself.
|
78
69
|
class << self
|
70
|
+
# @!method undetermined
|
71
|
+
# A 'null' special case for Status
|
72
|
+
# @return [Status]
|
73
|
+
#
|
74
|
+
# @!method not_submitted
|
75
|
+
# @return [Status]
|
76
|
+
#
|
77
|
+
# @!method passed
|
78
|
+
# @return [Status]
|
79
|
+
#
|
80
|
+
# @!method failed
|
81
|
+
# @return [Status]
|
82
|
+
#
|
83
|
+
# @!method running
|
84
|
+
# @return [Status]
|
85
|
+
#
|
86
|
+
# @!method queued
|
87
|
+
# @return [Status]
|
88
|
+
#
|
89
|
+
# @!method held
|
90
|
+
# @return [Status]
|
91
|
+
#
|
92
|
+
# @!method suspended
|
93
|
+
# @return [Status]
|
79
94
|
VALUES_HASH.each do |char, name|
|
80
95
|
define_method(name) do
|
81
96
|
OSC::Machete::Status.new(char)
|
@@ -84,22 +99,28 @@ class OSC::Machete::Status
|
|
84
99
|
end
|
85
100
|
|
86
101
|
# @!method undetermined?
|
87
|
-
#
|
88
|
-
|
102
|
+
# @return [Boolean] true if undetermined
|
103
|
+
|
89
104
|
# @!method not_submitted?
|
90
|
-
#
|
105
|
+
# @return [Boolean] true if not_submitted
|
106
|
+
|
91
107
|
# @!method failed?
|
92
|
-
#
|
108
|
+
# @return [Boolean] true if failed
|
109
|
+
|
93
110
|
# @!method passed?
|
94
|
-
#
|
111
|
+
# @return [Boolean] true if passed
|
112
|
+
|
95
113
|
# @!method held?
|
96
|
-
#
|
114
|
+
# @return [Boolean] true if held
|
115
|
+
|
97
116
|
# @!method queued?
|
98
|
-
#
|
117
|
+
# @return [Boolean] true if queued
|
118
|
+
|
99
119
|
# @!method running?
|
100
|
-
#
|
120
|
+
# @return [Boolean] true if running
|
121
|
+
|
101
122
|
# @!method suspended?
|
102
|
-
#
|
123
|
+
# @return [Boolean] true if suspended
|
103
124
|
VALUES_HASH.each do |char, name|
|
104
125
|
define_method("#{name}?") do
|
105
126
|
self == OSC::Machete::Status.new(char)
|
@@ -7,18 +7,32 @@ require 'pbs'
|
|
7
7
|
#
|
8
8
|
# == FIXME: This contains no state whatsoever. It should probably be changed into a module.
|
9
9
|
class OSC::Machete::TorqueHelper
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
# FIXME: Use ood_cluster gem
|
11
|
+
LIB = ENV['TORQUE_LIB'] || '/opt/torque/lib64'
|
12
|
+
BIN = ENV['TORQUE_BIN'] || '/opt/torque/bin'
|
13
|
+
HOSTS = {
|
14
|
+
'oakley' => 'oak-batch.osc.edu',
|
15
|
+
'ruby' => 'ruby-batch.osc.edu',
|
16
|
+
'quick' => 'quick-batch.osc.edu',
|
17
|
+
'owens' => 'owens-batch.ten.osc.edu',
|
18
|
+
:default => 'oak-batch.osc.edu'
|
19
|
+
}
|
20
|
+
|
21
|
+
class << self
|
22
|
+
#@!attribute default
|
23
|
+
# @return [TorqueHelper] default TorqueHelper instance to use
|
24
|
+
attr_writer :default
|
25
|
+
def default
|
26
|
+
@default ||= self::new()
|
27
|
+
end
|
14
28
|
end
|
15
29
|
|
16
30
|
# Returns an OSC::Machete::Status ValueObject for a char
|
17
31
|
#
|
18
32
|
# @param [String] char The Torque status char
|
19
33
|
#
|
20
|
-
# @example
|
21
|
-
# status_for_char("C") #=> OSC::Machete::Status.
|
34
|
+
# @example Passed
|
35
|
+
# status_for_char("C") #=> OSC::Machete::Status.passed
|
22
36
|
# @example Queued
|
23
37
|
# status_for_char("W") #=> OSC::Machete::Status.queued
|
24
38
|
#
|
@@ -51,12 +65,6 @@ class OSC::Machete::TorqueHelper
|
|
51
65
|
#
|
52
66
|
# Bills against the project specified by the primary group of the user.
|
53
67
|
def qsub(script, host: nil, depends_on: {}, account_string: nil)
|
54
|
-
# if the script is set to run on Oakley in PBS headers
|
55
|
-
# this is to obviate current torque filter defect in which
|
56
|
-
# a script with PBS header set to specify oak-batch ends
|
57
|
-
# isn't properly handled and the job gets limited to 4GB
|
58
|
-
pbs_job = get_pbs_job( host.nil? ? get_pbs_conn(script: script) : get_pbs_conn(host: host) )
|
59
|
-
|
60
68
|
headers = { depend: qsub_dependencies_header(depends_on) }
|
61
69
|
headers.clear if headers[:depend].empty?
|
62
70
|
|
@@ -70,7 +78,7 @@ class OSC::Machete::TorqueHelper
|
|
70
78
|
headers[PBS::ATTR[:A]] = default_account_string
|
71
79
|
end
|
72
80
|
|
73
|
-
|
81
|
+
pbs(host: host, script: script).submit_script(script, headers: headers, qsub: true)
|
74
82
|
end
|
75
83
|
|
76
84
|
# convert dependencies hash to a PBS header string
|
@@ -103,16 +111,10 @@ class OSC::Machete::TorqueHelper
|
|
103
111
|
#
|
104
112
|
# @return [Status] The job state
|
105
113
|
def qstat(pbsid, host: nil)
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
job_status = pbs_job.status
|
112
|
-
# Get the status char value from the job.
|
113
|
-
status_for_char job_status[:attribs][:job_state][0]
|
114
|
-
|
115
|
-
rescue PBS::UnkjobidError => err
|
114
|
+
id = pbsid.to_s
|
115
|
+
status = pbs(host: host, id: id).get_job(id, filters: [:job_state])
|
116
|
+
status_for_char status[id][:job_state][0] # get status from status char value
|
117
|
+
rescue PBS::UnkjobidError
|
116
118
|
OSC::Machete::Status.passed
|
117
119
|
end
|
118
120
|
|
@@ -122,54 +124,43 @@ class OSC::Machete::TorqueHelper
|
|
122
124
|
#
|
123
125
|
# @return [nil]
|
124
126
|
def qdel(pbsid, host: nil)
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
pbs_job.delete
|
130
|
-
|
131
|
-
rescue PBS::UnkjobidError => err
|
127
|
+
id = pbsid.to_s
|
128
|
+
pbs(host: host, id: id).delete_job(id)
|
129
|
+
rescue PBS::UnkjobidError
|
132
130
|
# Common use case where trying to delete a job that is no longer in the system.
|
133
131
|
end
|
134
132
|
|
135
|
-
|
133
|
+
def pbs(host: nil, id: nil, script: nil)
|
134
|
+
if host
|
135
|
+
# actually check if host is "oakley" i.e. a cluster key
|
136
|
+
host = HOSTS.fetch(host.to_s, host.to_s)
|
137
|
+
else
|
138
|
+
# try to determine host
|
139
|
+
key = host_from_pbsid(id) if id
|
140
|
+
key = host_from_script_pbs_header(script) if script && key.nil?
|
136
141
|
|
137
|
-
|
138
|
-
def get_pbs_job(conn, pbsid=nil)
|
139
|
-
pbsid.nil? ? PBS::Job.new(conn: conn) : PBS::Job.new(conn: conn, id: pbsid.to_s)
|
142
|
+
host = HOSTS.fetch(key, HOSTS.fetch(:default))
|
140
143
|
end
|
141
144
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
def get_pbs_conn(options={})
|
149
|
-
if options[:script]
|
150
|
-
PBS::Conn.batch(host_from_script_pbs_header(options[:script]))
|
151
|
-
elsif options[:pbsid]
|
152
|
-
PBS::Conn.batch(host_from_pbsid(options[:pbsid]))
|
153
|
-
elsif options[:host]
|
154
|
-
PBS::Conn.batch(options[:host])
|
155
|
-
else
|
156
|
-
PBS::Conn.batch("oakley")
|
157
|
-
end
|
158
|
-
end
|
145
|
+
PBS::Batch.new(
|
146
|
+
host: host,
|
147
|
+
lib: LIB,
|
148
|
+
bin: BIN
|
149
|
+
)
|
150
|
+
end
|
159
151
|
|
152
|
+
private
|
160
153
|
# return the name of the host to use based on the pbs header
|
161
154
|
# TODO: Think of a more efficient way to do this.
|
162
155
|
def host_from_script_pbs_header(script)
|
163
156
|
if (File.open(script) { |f| f.read =~ /#PBS -q @oak-batch/ })
|
164
157
|
"oakley"
|
165
|
-
elsif (File.open(script) { |f| f.read =~ /#PBS -q @opt-batch/ })
|
166
|
-
"glenn"
|
167
158
|
elsif (File.open(script) { |f| f.read =~ /#PBS -q @ruby-batch/ })
|
168
159
|
"ruby"
|
169
160
|
elsif (File.open(script) { |f| f.read =~ /#PBS -q @quick-batch/ })
|
170
161
|
"quick"
|
171
|
-
|
172
|
-
"
|
162
|
+
elsif (File.open(script) { |f| f.read =~ /#PBS -q @owens-batch/ })
|
163
|
+
"owens"
|
173
164
|
end
|
174
165
|
end
|
175
166
|
|
@@ -177,14 +168,12 @@ class OSC::Machete::TorqueHelper
|
|
177
168
|
def host_from_pbsid(pbsid)
|
178
169
|
if (pbsid =~ /oak-batch/ )
|
179
170
|
"oakley"
|
180
|
-
elsif (pbsid =~ /opt-batch/ )
|
181
|
-
"glenn"
|
182
171
|
elsif (pbsid.to_s =~ /^\d+$/ )
|
183
172
|
"ruby"
|
184
173
|
elsif (pbsid =~ /quick/ )
|
185
174
|
"quick"
|
186
|
-
|
187
|
-
"
|
175
|
+
elsif (pbsid =~ /owens/ )
|
176
|
+
"owens"
|
188
177
|
end
|
189
178
|
end
|
190
179
|
end
|
data/lib/osc/machete/user.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# Class that maintains the name and home identifiers of a User.
|
2
2
|
# Helper methods provided use the Etc module underneath.
|
3
3
|
#
|
4
|
+
# @deprecated Please use {http://www.rubydoc.info/gems/ood_support/OodSupport/User OodSupport::User} instead.
|
4
5
|
class OSC::Machete::User
|
5
6
|
|
6
7
|
attr_reader :name
|
@@ -19,6 +20,8 @@ class OSC::Machete::User
|
|
19
20
|
#
|
20
21
|
def initialize(username = Etc.getpwuid.name)
|
21
22
|
@name = username
|
23
|
+
|
24
|
+
warn "[DEPRECATION] `OSC::Machete::User` is deprecated. Please use `OodSupport::User` instead (see ood_support gem)."
|
22
25
|
end
|
23
26
|
|
24
27
|
# factory method to produce a User from specified uid
|
data/lib/osc/machete/version.rb
CHANGED
data/osc-machete.gemspec
CHANGED
@@ -18,6 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
19
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
20
|
spec.require_paths = ["lib"]
|
21
|
+
spec.required_ruby_version = '~> 2.2'
|
21
22
|
|
22
23
|
spec.add_development_dependency "bundler", "~> 1.3"
|
23
24
|
spec.add_development_dependency "rake"
|
@@ -25,6 +26,6 @@ Gem::Specification.new do |spec|
|
|
25
26
|
spec.add_development_dependency "minitest", ">= 5.0"
|
26
27
|
|
27
28
|
spec.add_runtime_dependency "mustache"
|
28
|
-
spec.add_runtime_dependency "pbs", "~>
|
29
|
+
spec.add_runtime_dependency "pbs", "~> 2.0"
|
29
30
|
end
|
30
31
|
|
data/test/test_job_dir.rb
CHANGED
@@ -34,6 +34,6 @@ class TestJobDir < Minitest::Test
|
|
34
34
|
# Create unique directory
|
35
35
|
new_jobdir = OSC::Machete::JobDir.new(@parent).new_jobdir
|
36
36
|
Dir.mkdir(new_jobdir)
|
37
|
-
assert Dir.
|
37
|
+
assert Dir.exist?("#{@parent}/9"), "Directory was not created: #{@parent}/9"
|
38
38
|
end
|
39
39
|
end
|
data/test/test_location.rb
CHANGED
@@ -24,41 +24,41 @@ class TestLocation < Minitest::Test
|
|
24
24
|
def test_render_default_replace_template
|
25
25
|
setup_render
|
26
26
|
@location1.render("")
|
27
|
-
assert_equal true, File.
|
28
|
-
assert_equal false, File.
|
27
|
+
assert_equal true, File.exist?("#{@dir1}/file.txt")
|
28
|
+
assert_equal false, File.exist?("#{@dir1}/file.txt.mustache")
|
29
29
|
end
|
30
30
|
|
31
31
|
def test_render_user_replace_template
|
32
32
|
setup_render
|
33
33
|
@location1.render("", {replace: true})
|
34
|
-
assert_equal true, File.
|
35
|
-
assert_equal false, File.
|
34
|
+
assert_equal true, File.exist?("#{@dir1}/file.txt")
|
35
|
+
assert_equal false, File.exist?("#{@dir1}/file.txt.mustache")
|
36
36
|
end
|
37
37
|
|
38
38
|
def test_render_user_doesnt_replace_template
|
39
39
|
setup_render
|
40
40
|
@location1.render("", {replace: false})
|
41
|
-
assert_equal true, File.
|
42
|
-
assert_equal true, File.
|
41
|
+
assert_equal true, File.exist?("#{@dir1}/file.txt")
|
42
|
+
assert_equal true, File.exist?("#{@dir1}/file.txt.mustache")
|
43
43
|
end
|
44
44
|
|
45
45
|
def test_copy_to_shouldnt_copy_developer_files
|
46
46
|
setup_copy_to
|
47
47
|
|
48
48
|
@location1.copy_to(@dir2)
|
49
|
-
assert_equal true, Dir.
|
50
|
-
assert_equal false, Dir.
|
51
|
-
assert_equal false, Dir.
|
52
|
-
assert_equal false, Dir.
|
53
|
-
assert_equal true, Dir.
|
54
|
-
assert_equal true, File.
|
55
|
-
assert_equal false, File.
|
56
|
-
assert_equal true, File.
|
57
|
-
assert_equal false, File.
|
58
|
-
assert_equal false, File.
|
59
|
-
assert_equal false, File.
|
60
|
-
assert_equal true, File.
|
61
|
-
assert_equal false, File.
|
49
|
+
assert_equal true, Dir.exist?("#{@dir2}")
|
50
|
+
assert_equal false, Dir.exist?("#{@dir2}/.git")
|
51
|
+
assert_equal false, Dir.exist?("#{@dir2}/.svn")
|
52
|
+
assert_equal false, Dir.exist?("#{@dir2}/test.dir.1")
|
53
|
+
assert_equal true, Dir.exist?("#{@dir2}/test.dir.2")
|
54
|
+
assert_equal true, File.exist?("#{@dir2}/test.1")
|
55
|
+
assert_equal false, File.exist?("#{@dir2}/test.2")
|
56
|
+
assert_equal true, File.exist?("#{@dir2}/test.3")
|
57
|
+
assert_equal false, File.exist?("#{@dir2}/test.4")
|
58
|
+
assert_equal false, File.exist?("#{@dir2}/test.dir.2/test.1")
|
59
|
+
assert_equal false, File.exist?("#{@dir2}/test.dir.2/test.2")
|
60
|
+
assert_equal true, File.exist?("#{@dir2}/test.dir.2/test.4")
|
61
|
+
assert_equal false, File.exist?("#{@dir2}/.gitignore")
|
62
62
|
end
|
63
63
|
|
64
64
|
|
data/test/test_torque_helper.rb
CHANGED
@@ -58,81 +58,81 @@ class TestTorqueHelper < Minitest::Test
|
|
58
58
|
# end
|
59
59
|
|
60
60
|
def test_qstat_state_no_job
|
61
|
-
PBS::
|
61
|
+
PBS::Batch.any_instance.stubs(:get_job).raises(PBS::UnkjobidError, "Unknown Job Id")
|
62
62
|
assert_equal @job_state_completed, @shell.qstat("")
|
63
63
|
assert_equal @job_state_completed, @shell.qstat(nil)
|
64
|
-
PBS::
|
64
|
+
PBS::Batch.any_instance.unstub(:get_job)
|
65
65
|
end
|
66
66
|
|
67
67
|
# Test that qstat returns Running job StatusValue
|
68
68
|
def test_qstat_state_running_oakley
|
69
|
-
PBS::
|
69
|
+
PBS::Batch.any_instance.stubs(:get_job).returns({ "123.oak-batch.osc.edu" => { :job_state => "R" }})
|
70
70
|
assert_equal @job_state_running, @shell.qstat("123.oak-batch.osc.edu")
|
71
|
-
PBS::
|
71
|
+
PBS::Batch.any_instance.unstub(:get_job)
|
72
72
|
end
|
73
73
|
|
74
74
|
# Test that qstat returns Queued job StatusValue
|
75
75
|
def test_qstat_state_queued_oakley
|
76
|
-
PBS::
|
76
|
+
PBS::Batch.any_instance.stubs(:get_job).returns({ "123.oak-batch.osc.edu" => { :job_state => "Q" }})
|
77
77
|
assert_equal @job_state_queued, @shell.qstat("123.oak-batch.osc.edu")
|
78
|
-
PBS::
|
78
|
+
PBS::Batch.any_instance.unstub(:get_job)
|
79
79
|
end
|
80
80
|
|
81
81
|
# Test that qstat returns Queued job StatusValue
|
82
82
|
def test_qstat_state_running_ruby
|
83
|
-
PBS::
|
83
|
+
PBS::Batch.any_instance.stubs(:get_job).returns({ "12398765" => { :job_state => "Q" }})
|
84
84
|
assert_equal @job_state_queued, @shell.qstat("12398765")
|
85
|
-
PBS::
|
85
|
+
PBS::Batch.any_instance.unstub(:get_job)
|
86
86
|
end
|
87
87
|
|
88
88
|
# Test that qstat returns Completed job StatusValue when state is nil.
|
89
89
|
def test_qstat_state_completed_oakley
|
90
|
-
PBS::
|
90
|
+
PBS::Batch.any_instance.stubs(:get_job).raises(PBS::UnkjobidError, "Unknown Job Id Error")
|
91
91
|
assert_equal @job_state_completed, @shell.qstat("123.oak-batch.osc.edu")
|
92
|
-
PBS::
|
92
|
+
PBS::Batch.any_instance.unstub(:get_job)
|
93
93
|
|
94
|
-
PBS::
|
94
|
+
PBS::Batch.any_instance.stubs(:get_job).raises(PBS::UnkjobidError, "Unknown Job Id")
|
95
95
|
assert_equal @job_state_completed, @shell.qstat("123.oak-batch.osc.edu")
|
96
|
-
PBS::
|
96
|
+
PBS::Batch.any_instance.unstub(:get_job)
|
97
97
|
end
|
98
98
|
|
99
99
|
# Test that qdel works for oakley
|
100
100
|
def test_qdel_oakley_ok
|
101
|
-
PBS::
|
101
|
+
PBS::Batch.any_instance.stubs(:delete_job).returns(true)
|
102
102
|
assert_equal true, @shell.qdel("123.oak-batch.osc.edu")
|
103
|
-
PBS::
|
103
|
+
PBS::Batch.any_instance.unstub(:delete_job)
|
104
104
|
end
|
105
105
|
|
106
106
|
# Test that qdel works for quick batch
|
107
107
|
def test_qdel_quick
|
108
|
-
PBS::
|
108
|
+
PBS::Batch.any_instance.stubs(:delete_job).returns(true)
|
109
109
|
assert_equal true, @shell.qdel("123.quick-batch.osc.edu")
|
110
|
-
PBS::
|
110
|
+
PBS::Batch.any_instance.unstub(:delete_job)
|
111
111
|
end
|
112
112
|
|
113
113
|
# Test that qdel works for Ruby cluster
|
114
114
|
def test_qdel_ruby
|
115
|
-
PBS::
|
115
|
+
PBS::Batch.any_instance.stubs(:delete_job).returns(true)
|
116
116
|
assert_equal true, @shell.qdel("12365478")
|
117
|
-
PBS::
|
117
|
+
PBS::Batch.any_instance.unstub(:delete_job)
|
118
118
|
end
|
119
119
|
|
120
120
|
# Test that qdel throws exception on PBS exception
|
121
121
|
def test_qdel_throws_exception
|
122
|
-
PBS::
|
122
|
+
PBS::Batch.any_instance.stubs(:delete_job).raises(PBS::Error)
|
123
123
|
assert_raises(PBS::Error) { @shell.qdel("123.quick-batch.osc.edu") }
|
124
|
-
PBS::
|
124
|
+
PBS::Batch.any_instance.unstub(:delete_job)
|
125
125
|
|
126
|
-
PBS::
|
126
|
+
PBS::Batch.any_instance.stubs(:delete_job).raises(PBS::SystemError)
|
127
127
|
assert_raises(PBS::SystemError) { @shell.qdel("123.quick-batch.osc.edu") }
|
128
|
-
PBS::
|
128
|
+
PBS::Batch.any_instance.unstub(:delete_job)
|
129
129
|
end
|
130
130
|
|
131
131
|
# Test that qdel doesn't throw exception if Unknown Job Id exception
|
132
132
|
def test_qdel_doesnt_throw_exception_on_unknown_job_id
|
133
|
-
PBS::
|
133
|
+
PBS::Batch.any_instance.stubs(:delete_job).raises(PBS::UnkjobidError)
|
134
134
|
@shell.qdel("123.quick-batch.osc.edu")
|
135
|
-
PBS::
|
135
|
+
PBS::Batch.any_instance.unstub(:delete_job)
|
136
136
|
end
|
137
137
|
|
138
138
|
def assert_qsub_dependency_list(dependency_list, dependencies, host=nil)
|
@@ -188,22 +188,67 @@ class TestTorqueHelper < Minitest::Test
|
|
188
188
|
end
|
189
189
|
|
190
190
|
def test_account_string_passed_into_qsub_used_during_submit_call
|
191
|
-
PBS::
|
191
|
+
PBS::Batch.any_instance.expects(:submit_script).with(@script_oakley, has_entry(headers: {Account_Name: "XXX"})).returns('1234598.oak-batch.osc.edu')
|
192
192
|
@shell.qsub(@script_oakley, account_string: "XXX")
|
193
|
-
PBS::
|
193
|
+
PBS::Batch.any_instance.unstub(:submit_script)
|
194
194
|
end
|
195
195
|
|
196
196
|
def test_default_account_string_used_in_qsub_during_submit_call
|
197
197
|
@shell.stubs(:default_account_string).returns("PZS3000")
|
198
198
|
|
199
|
-
PBS::
|
199
|
+
PBS::Batch.any_instance.expects(:submit_script).with(@script_oakley, has_entry(headers: {Account_Name: @shell.default_account_string})).returns('1234598.oak-batch.osc.edu')
|
200
200
|
@shell.qsub(@script_oakley)
|
201
201
|
|
202
202
|
@shell.stubs(:default_account_string).returns("appl")
|
203
|
-
PBS::
|
203
|
+
PBS::Batch.any_instance.expects(:submit_script).with(@script_oakley, has_entry(headers: {})).returns('1234598.oak-batch.osc.edu')
|
204
204
|
@shell.qsub(@script_oakley)
|
205
205
|
|
206
|
-
PBS::
|
206
|
+
PBS::Batch.any_instance.unstub(:submit_script)
|
207
207
|
@shell.unstub(:default_account_string)
|
208
208
|
end
|
209
|
+
|
210
|
+
def test_pbs_default_host
|
211
|
+
s = @shell.pbs
|
212
|
+
assert_equal 'oak-batch.osc.edu', s.host
|
213
|
+
assert_equal OSC::Machete::TorqueHelper::LIB, s.lib.to_s
|
214
|
+
assert_equal OSC::Machete::TorqueHelper::BIN, s.bin.to_s
|
215
|
+
end
|
216
|
+
|
217
|
+
def test_pbs_host_variations
|
218
|
+
# you can use the cluster ids
|
219
|
+
assert_equal 'ruby-batch.osc.edu', @shell.pbs(host: 'ruby').host
|
220
|
+
|
221
|
+
# or you can use the host itself
|
222
|
+
assert_equal 'ruby-batch.osc.edu', @shell.pbs(host: 'ruby-batch.osc.edu').host
|
223
|
+
assert_equal '@ruby-batch', @shell.pbs(host: '@ruby-batch').host
|
224
|
+
|
225
|
+
assert_equal 'ruby-batch.osc.edu', @shell.pbs(id: '4567').host
|
226
|
+
assert_equal 'ruby-batch.osc.edu', @shell.pbs(script: @script_ruby).host
|
227
|
+
assert_equal 'oak-batch.osc.edu', @shell.pbs(script: @script_oakley).host
|
228
|
+
end
|
229
|
+
|
230
|
+
def test_setting_default_torque_helper
|
231
|
+
d = OSC::Machete::TorqueHelper.default
|
232
|
+
|
233
|
+
assert_equal 'oak-batch.osc.edu', OSC::Machete::TorqueHelper.default.pbs.host
|
234
|
+
|
235
|
+
# this is an example of how you can quickly modify the default behavior of
|
236
|
+
# a TorqueHelper instance to provide a new host, id, and script
|
237
|
+
d2 = OSC::Machete::TorqueHelper.new
|
238
|
+
class << d2
|
239
|
+
def pbs(host: nil, id: nil, script: nil)
|
240
|
+
PBS::Batch.new(
|
241
|
+
host: "ruby-batch.osc.edu",
|
242
|
+
lib: LIB,
|
243
|
+
bin: BIN
|
244
|
+
)
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
OSC::Machete::TorqueHelper.default = d2
|
249
|
+
|
250
|
+
assert_equal 'ruby-batch.osc.edu', OSC::Machete::TorqueHelper.default.pbs.host
|
251
|
+
|
252
|
+
OSC::Machete::TorqueHelper.default = d
|
253
|
+
end
|
209
254
|
end
|
@@ -2,6 +2,7 @@ require 'minitest/autorun'
|
|
2
2
|
require 'osc/machete'
|
3
3
|
require 'pbs'
|
4
4
|
require 'mocha/setup'
|
5
|
+
require 'socket'
|
5
6
|
|
6
7
|
# test helper class
|
7
8
|
class TestTorqueHelperLive < Minitest::Test
|
@@ -29,7 +30,7 @@ class TestTorqueHelperLive < Minitest::Test
|
|
29
30
|
# This raises an issue mentioning that it is not being submitted on the
|
30
31
|
# correct host, comment out the raise to skip the live tests.
|
31
32
|
# Maybe this would be better accomplished with a separate rake task.
|
32
|
-
@submit_host = "
|
33
|
+
@submit_host = "webdev02.hpc.osc.edu"
|
33
34
|
|
34
35
|
@job_state_queued = OSC::Machete::Status.queued
|
35
36
|
@job_state_completed = OSC::Machete::Status.passed
|
@@ -70,11 +71,11 @@ class TestTorqueHelperLive < Minitest::Test
|
|
70
71
|
|
71
72
|
# Qstat it to make sure it's queued.
|
72
73
|
live_status = torque.qstat(live_job)
|
73
|
-
|
74
|
+
assert_includes OSC::Machete::Status.active_values, live_status
|
74
75
|
|
75
76
|
# Delete it and assert true returned.
|
76
77
|
live_delete_status = torque.qdel(live_job)
|
77
|
-
assert_equal
|
78
|
+
assert_equal 0, live_delete_status
|
78
79
|
else
|
79
80
|
puts "Run test 'test_qsub_oakley' on the batch system from #{@submit_host}."
|
80
81
|
end
|
@@ -101,11 +102,11 @@ class TestTorqueHelperLive < Minitest::Test
|
|
101
102
|
|
102
103
|
# Qstat it to make sure it's queued.
|
103
104
|
live_status = torque.qstat(live_job)
|
104
|
-
|
105
|
+
assert_includes OSC::Machete::Status.active_values, live_status
|
105
106
|
|
106
107
|
# Delete it and assert true returned.
|
107
108
|
live_delete_status = torque.qdel(live_job)
|
108
|
-
assert_equal
|
109
|
+
assert_equal 0, live_delete_status
|
109
110
|
else
|
110
111
|
puts "Run test 'test_qsub_ruby_with_oakley_script' on the batch system from #{@submit_host}."
|
111
112
|
end
|
@@ -127,15 +128,15 @@ class TestTorqueHelperLive < Minitest::Test
|
|
127
128
|
if Socket.gethostname == @submit_host
|
128
129
|
# Submit a small job.
|
129
130
|
live_job = torque.qsub(@script_ruby)
|
130
|
-
assert_match
|
131
|
+
assert_match(/^\d+$/, live_job)
|
131
132
|
|
132
133
|
# Qstat it to make sure it's queued.
|
133
134
|
live_status = torque.qstat(live_job)
|
134
|
-
|
135
|
+
assert_includes OSC::Machete::Status.active_values, live_status
|
135
136
|
|
136
137
|
# Delete it and assert true returned.
|
137
138
|
live_delete_status = torque.qdel(live_job)
|
138
|
-
assert_equal
|
139
|
+
assert_equal 0, live_delete_status
|
139
140
|
else
|
140
141
|
puts "Run test 'test_qsub_ruby' on the batch system from #{@submit_host}."
|
141
142
|
end
|
@@ -156,15 +157,15 @@ class TestTorqueHelperLive < Minitest::Test
|
|
156
157
|
if Socket.gethostname == @submit_host
|
157
158
|
# Submit a small job.
|
158
159
|
live_job = torque.qsub(@script_quick, host: 'quick')
|
159
|
-
assert_match
|
160
|
+
assert_match(/\d+.quick-batch.osc.edu/, live_job)
|
160
161
|
|
161
162
|
# Qstat it to make sure it's queued.
|
162
163
|
live_status = torque.qstat(live_job)
|
163
|
-
|
164
|
+
assert_includes OSC::Machete::Status.active_values, live_status
|
164
165
|
|
165
166
|
# Delete it and assert true returned.
|
166
167
|
live_delete_status = torque.qdel(live_job)
|
167
|
-
assert_equal
|
168
|
+
assert_equal 0, live_delete_status
|
168
169
|
else
|
169
170
|
puts "Run test 'test_qsub_quick' on the batch system from #{@submit_host}."
|
170
171
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: osc-machete
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eric Franz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-09-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -86,14 +86,14 @@ dependencies:
|
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '
|
89
|
+
version: '2.0'
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: '
|
96
|
+
version: '2.0'
|
97
97
|
description: Common interface for PBS (and eventually other resource managers and
|
98
98
|
batch schedulers - currently OSC specific)
|
99
99
|
email:
|
@@ -144,9 +144,9 @@ require_paths:
|
|
144
144
|
- lib
|
145
145
|
required_ruby_version: !ruby/object:Gem::Requirement
|
146
146
|
requirements:
|
147
|
-
- - "
|
147
|
+
- - "~>"
|
148
148
|
- !ruby/object:Gem::Version
|
149
|
-
version: '
|
149
|
+
version: '2.2'
|
150
150
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
151
151
|
requirements:
|
152
152
|
- - ">="
|
@@ -154,7 +154,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
154
154
|
version: '0'
|
155
155
|
requirements: []
|
156
156
|
rubyforge_project:
|
157
|
-
rubygems_version: 2.4.
|
157
|
+
rubygems_version: 2.4.8
|
158
158
|
signing_key:
|
159
159
|
specification_version: 4
|
160
160
|
summary: Common interface for working with HPC batch jobs (currently OSC specific)
|
@@ -175,4 +175,3 @@ test_files:
|
|
175
175
|
- test/test_status.rb
|
176
176
|
- test/test_torque_helper.rb
|
177
177
|
- test/test_torque_helper_live.rb
|
178
|
-
has_rdoc:
|