girdle 0.0.1
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.
- data/.gitignore +17 -0
- data/Gemfile +7 -0
- data/Guardfile +15 -0
- data/README.markdown +28 -0
- data/Rakefile +2 -0
- data/girdle.gemspec +27 -0
- data/lib/girdle.rb +86 -0
- data/lib/girdle/controller.rb +32 -0
- data/lib/girdle/grid.rb +33 -0
- data/lib/girdle/job.rb +104 -0
- data/lib/girdle/specification.rb +56 -0
- data/lib/girdle/task.rb +16 -0
- data/lib/girdle/version.rb +3 -0
- data/spec/girdle/controller_spec.rb +67 -0
- data/spec/girdle/grid_spec.rb +57 -0
- data/spec/girdle/job_spec.rb +178 -0
- data/spec/girdle/specification_spec.rb +68 -0
- data/spec/girdle/task_spec.rb +19 -0
- data/spec/girdle_spec.rb +44 -0
- data/spec/spec_helper.rb +7 -0
- metadata +160 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
guard 'minitest' do
|
5
|
+
# with Minitest::Unit
|
6
|
+
watch(%r|^test/test_(.*)\.rb|)
|
7
|
+
watch(%r|^lib/(.*)([^/]+)\.rb|) { |m| "test/#{m[1]}test_#{m[2]}.rb" }
|
8
|
+
watch(%r|^test/test_helper\.rb|) { "test" }
|
9
|
+
|
10
|
+
# with Minitest::Spec
|
11
|
+
watch(%r|^spec/(.*)_spec\.rb|)
|
12
|
+
watch(%r|^lib/(.*)\.rb|) { |m| "spec/#{m[1]}_spec.rb" }
|
13
|
+
watch(%r|^lib/girdle/(.*)\.rb|) { |m| "spec/#{m[1]}_spec.rb" }
|
14
|
+
watch(%r|^spec/spec_helper\.rb|) { "spec" }
|
15
|
+
end
|
data/README.markdown
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
Girdle
|
2
|
+
=======
|
3
|
+
|
4
|
+
A client for submitting and managing Xgrid jobs.
|
5
|
+
|
6
|
+
License
|
7
|
+
-------
|
8
|
+
|
9
|
+
Copyright (c) 2011 Jamie Hodge
|
10
|
+
|
11
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
12
|
+
a copy of this software and associated documentation files (the
|
13
|
+
"Software"), to deal in the Software without restriction, including
|
14
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
15
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
16
|
+
permit persons to whom the Software is furnished to do so, subject to
|
17
|
+
the following conditions:
|
18
|
+
|
19
|
+
The above copyright notice and this permission notice shall be
|
20
|
+
included in all copies or substantial portions of the Software.
|
21
|
+
|
22
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
23
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
24
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
25
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
26
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
27
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
28
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
data/girdle.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/girdle/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Jamie Hodge"]
|
6
|
+
gem.email = ["jamiehodge@me.com"]
|
7
|
+
gem.description = %q{An Xgrid client}
|
8
|
+
gem.summary = %q{A client for submitting and managing Xgrid jobs}
|
9
|
+
gem.homepage = 'http://github.com/jamiehodge/girdle'
|
10
|
+
|
11
|
+
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
12
|
+
gem.files = `git ls-files`.split("\n")
|
13
|
+
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
14
|
+
gem.name = "girdle"
|
15
|
+
gem.require_paths = ['lib']
|
16
|
+
gem.version = Girdle::VERSION
|
17
|
+
|
18
|
+
gem.add_development_dependency 'bundler'
|
19
|
+
gem.add_development_dependency 'guard'
|
20
|
+
gem.add_development_dependency 'guard-minitest'
|
21
|
+
gem.add_development_dependency 'rb-fsevent'
|
22
|
+
gem.add_development_dependency 'growl_notify'
|
23
|
+
gem.add_development_dependency 'mocha'
|
24
|
+
|
25
|
+
gem.add_dependency 'nokogiri'
|
26
|
+
gem.add_dependency 'nokogiri-plist'
|
27
|
+
end
|
data/lib/girdle.rb
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
require 'nokogiri'
|
3
|
+
require 'nokogiri-plist'
|
4
|
+
|
5
|
+
require_relative 'girdle/version'
|
6
|
+
|
7
|
+
require_relative 'girdle/task'
|
8
|
+
require_relative 'girdle/specification'
|
9
|
+
require_relative 'girdle/job'
|
10
|
+
|
11
|
+
require_relative 'girdle/grid'
|
12
|
+
require_relative 'girdle/controller'
|
13
|
+
|
14
|
+
module Girdle
|
15
|
+
extend self
|
16
|
+
|
17
|
+
attr_writer :xgrid, :hostname, :auth,
|
18
|
+
:password, :format, :failover, :autocopy
|
19
|
+
|
20
|
+
def xgrid
|
21
|
+
@xgrid ||= '/usr/bin/xgrid'
|
22
|
+
end
|
23
|
+
|
24
|
+
def hostname
|
25
|
+
@hostname ||= 'localhost'
|
26
|
+
end
|
27
|
+
|
28
|
+
# None, Password, Kerberos
|
29
|
+
def auth
|
30
|
+
@auth ||= 'None'
|
31
|
+
end
|
32
|
+
|
33
|
+
def password
|
34
|
+
@password ||= ''
|
35
|
+
end
|
36
|
+
|
37
|
+
# plain, xml
|
38
|
+
def format
|
39
|
+
@format ||= 'xml'
|
40
|
+
end
|
41
|
+
|
42
|
+
# YES, NO
|
43
|
+
def failover
|
44
|
+
@failover ||= 'YES'
|
45
|
+
end
|
46
|
+
|
47
|
+
# YES, NO
|
48
|
+
def autocopy
|
49
|
+
@autocopy ||= 'YES'
|
50
|
+
end
|
51
|
+
|
52
|
+
def run(options = {})
|
53
|
+
options = default_options.merge(options)
|
54
|
+
result = `#{xgrid} #{options_format(options)}`
|
55
|
+
parse(result) if $?.to_i == 0
|
56
|
+
end
|
57
|
+
|
58
|
+
def run_batch(xml, options = {})
|
59
|
+
options = default_options.merge(options)
|
60
|
+
result = `#{xml} | #{xgrid} #{options_format(options)} -`
|
61
|
+
parse(result) if $?.to_i == 0
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def options_format(options)
|
67
|
+
options.map { |k,v| k == :cmd ? v : "-#{k} #{v}" }.join(' ')
|
68
|
+
end
|
69
|
+
|
70
|
+
def default_options
|
71
|
+
opts = {
|
72
|
+
hostname: hostname,
|
73
|
+
auth: auth,
|
74
|
+
format: format,
|
75
|
+
failover: failover,
|
76
|
+
autocopy: autocopy
|
77
|
+
}
|
78
|
+
opts[:password] == password if auth == 'Password'
|
79
|
+
opts
|
80
|
+
end
|
81
|
+
|
82
|
+
def parse(xml)
|
83
|
+
Nokogiri::PList(xml)
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Girdle
|
2
|
+
|
3
|
+
class Controller
|
4
|
+
|
5
|
+
attr_reader :id
|
6
|
+
|
7
|
+
def initialize(id)
|
8
|
+
@id = id
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.list
|
12
|
+
Girdle.run(controller: 'list')['controllerList']
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.role
|
16
|
+
Girdle.run(controller: 'role')['controllerRole']
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.promote(role)
|
20
|
+
Girdle.run(
|
21
|
+
controller: 'promote', role: role.to_s.upcase
|
22
|
+
)['controllerRole']
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.autopromote(role)
|
26
|
+
Girdle.run(
|
27
|
+
controller: 'autopromote', role: role.to_s.upcase
|
28
|
+
)['controllerRole']
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
data/lib/girdle/grid.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
module Girdle
|
2
|
+
|
3
|
+
class Grid
|
4
|
+
|
5
|
+
attr_reader :id
|
6
|
+
|
7
|
+
def initialize(id)
|
8
|
+
@id = id
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.list
|
12
|
+
Girdle.run(grid: 'list')
|
13
|
+
end
|
14
|
+
|
15
|
+
def attributes
|
16
|
+
Girdle.run(grid: 'attributes', gid: id)['gridAttributes']
|
17
|
+
end
|
18
|
+
|
19
|
+
def name
|
20
|
+
attributes['name']
|
21
|
+
end
|
22
|
+
|
23
|
+
def megahertz
|
24
|
+
attributes['gridMegahertz']
|
25
|
+
end
|
26
|
+
|
27
|
+
def is_default?
|
28
|
+
attributes['isDefault'] == 'YES'
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
data/lib/girdle/job.rb
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
module Girdle
|
2
|
+
|
3
|
+
class Job
|
4
|
+
|
5
|
+
attr_reader :name, :id
|
6
|
+
|
7
|
+
def initialize(id)
|
8
|
+
@id = id
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.list
|
12
|
+
Girdle.run(job: 'list')['jobList']
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.submit(cmd)
|
16
|
+
Girdle.run(job: 'submit', cmd: cmd)['jobIdentifier']
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.run(cmd)
|
20
|
+
Girdle.run(job: 'run', cmd: cmd)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.batch(xml)
|
24
|
+
Girdle.run_batch(xml, job: 'batch')['jobIdentifier']
|
25
|
+
end
|
26
|
+
|
27
|
+
def attributes
|
28
|
+
Girdle.run(job: 'attributes', id: id)['jobAttributes']
|
29
|
+
end
|
30
|
+
|
31
|
+
def active_cpu_power
|
32
|
+
attributes['activeCPUPower'].to_i
|
33
|
+
end
|
34
|
+
|
35
|
+
def date_now
|
36
|
+
attributes['dateNow']
|
37
|
+
end
|
38
|
+
|
39
|
+
def date_started
|
40
|
+
attributes['dateStarted']
|
41
|
+
end
|
42
|
+
|
43
|
+
def date_stopped
|
44
|
+
attributes['dateStopped']
|
45
|
+
end
|
46
|
+
|
47
|
+
def date_submitted
|
48
|
+
attributes['dateSubmitted']
|
49
|
+
end
|
50
|
+
|
51
|
+
def status
|
52
|
+
attributes['jobStatus'].downcase.to_sym
|
53
|
+
end
|
54
|
+
|
55
|
+
def name
|
56
|
+
attributes['name']
|
57
|
+
end
|
58
|
+
|
59
|
+
def percent_done
|
60
|
+
attributes['percentDone']
|
61
|
+
end
|
62
|
+
|
63
|
+
def task_count
|
64
|
+
attributes['taskCount'].to_i
|
65
|
+
end
|
66
|
+
|
67
|
+
def undone_task_count
|
68
|
+
attributes['undoneTaskCount'].to_i
|
69
|
+
end
|
70
|
+
|
71
|
+
def results
|
72
|
+
Girdle.run(job: 'results', id: id)
|
73
|
+
end
|
74
|
+
|
75
|
+
def specification
|
76
|
+
Girdle.run(job: 'specification', id: id)['jobSpecification']
|
77
|
+
end
|
78
|
+
|
79
|
+
def log
|
80
|
+
Girdle.run(job: 'log', id: id)
|
81
|
+
end
|
82
|
+
|
83
|
+
def stop
|
84
|
+
Girdle.run(job: 'stop', id: id)
|
85
|
+
end
|
86
|
+
|
87
|
+
def suspend
|
88
|
+
Girdle.run(job: 'suspend', id: id)
|
89
|
+
end
|
90
|
+
|
91
|
+
def resume
|
92
|
+
Girdle.run(job: 'resume', id: id)
|
93
|
+
end
|
94
|
+
|
95
|
+
def delete
|
96
|
+
Girdle.run(job: 'delete', id: id)
|
97
|
+
end
|
98
|
+
|
99
|
+
def restart
|
100
|
+
Girdle.run(job: 'restart', id: id)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Girdle
|
2
|
+
|
3
|
+
class Specification
|
4
|
+
|
5
|
+
attr_accessor :name, :notification_email, :tasks
|
6
|
+
|
7
|
+
def initialize(options = {})
|
8
|
+
@name = options[:name]
|
9
|
+
@notification_email = options[:notification_email]
|
10
|
+
@tasks = options[:tasks] || []
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_plist
|
14
|
+
Nokogiri::XML::Builder.new do |xml|
|
15
|
+
xml.doc.create_internal_subset(
|
16
|
+
'plist',
|
17
|
+
'-//Apple Computer//DTD PLIST 1.0//EN',
|
18
|
+
'http://www.apple.com/DTDs/PropertyList-1.0.dtd'
|
19
|
+
)
|
20
|
+
xml.plist(:version => '1.0') do
|
21
|
+
xml.array do
|
22
|
+
xml.key 'name'
|
23
|
+
xml.string name
|
24
|
+
xml.key 'notificationEmail'
|
25
|
+
xml.string notification_email
|
26
|
+
xml.key 'taskSpecifications'
|
27
|
+
xml.dict do
|
28
|
+
tasks.each do |task|
|
29
|
+
xml.key 'name'
|
30
|
+
xml.string task.name
|
31
|
+
xml.dict do
|
32
|
+
xml.key 'arguments'
|
33
|
+
xml.array do
|
34
|
+
task.arguments.each do |argument|
|
35
|
+
xml.string argument
|
36
|
+
end
|
37
|
+
end
|
38
|
+
xml.key 'command'
|
39
|
+
xml.string task.command
|
40
|
+
xml.key 'dependsOnTasks'
|
41
|
+
xml.array do
|
42
|
+
task.depends_on.each do |dependency|
|
43
|
+
xml.string dependency
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end.to_xml
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
data/lib/girdle/task.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
module Girdle
|
2
|
+
|
3
|
+
class Task
|
4
|
+
|
5
|
+
attr_reader :name, :command, :arguments, :depends_on
|
6
|
+
|
7
|
+
def initialize(options = {})
|
8
|
+
@name = options[:name]
|
9
|
+
@command = options[:command]
|
10
|
+
@arguments = options[:arguments]
|
11
|
+
@depends_on = options[:depends_on]
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
describe Girdle::Controller do
|
4
|
+
|
5
|
+
it 'must have id attribute' do
|
6
|
+
grid = Girdle::Controller.new(123)
|
7
|
+
grid.id.must_equal 123
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'must retrieve list of failover controllers' do
|
11
|
+
Girdle.expects(:run).
|
12
|
+
with(controller: 'list').
|
13
|
+
returns('controllerList' => Hash.new)
|
14
|
+
list = Girdle::Controller.list
|
15
|
+
list.must_equal Hash.new
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'must retrieve role of controller' do
|
19
|
+
Girdle.expects(:run).
|
20
|
+
with(controller: 'role').
|
21
|
+
returns('controllerRole' => 'MASTER')
|
22
|
+
role = Girdle::Controller.role
|
23
|
+
role.must_equal 'MASTER'
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '::promote' do
|
27
|
+
|
28
|
+
it 'must promote the controller to MASTER role' do
|
29
|
+
Girdle.expects(:run).
|
30
|
+
with(controller: 'promote', role: 'MASTER').
|
31
|
+
returns('controllerRole' => 'MASTER')
|
32
|
+
role = Girdle::Controller.promote(:master)
|
33
|
+
role.must_equal 'MASTER'
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'must promote the controller to PASSIVE role' do
|
37
|
+
Girdle.expects(:run).
|
38
|
+
with(controller: 'promote', role: 'PASSIVE').
|
39
|
+
returns('controllerRole' => 'PASSIVE')
|
40
|
+
role = Girdle::Controller.promote(:passive)
|
41
|
+
role.must_equal 'PASSIVE'
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
describe '::autopromote' do
|
47
|
+
|
48
|
+
it 'must autopromote the controller to MASTER role' do
|
49
|
+
Girdle.expects(:run).
|
50
|
+
with(controller: 'autopromote', role: 'MASTER').
|
51
|
+
returns('controllerRole' => 'MASTER')
|
52
|
+
role = Girdle::Controller.autopromote(:master)
|
53
|
+
role.must_equal 'MASTER'
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'must autopromote the controller to PASSIVE role' do
|
57
|
+
Girdle.expects(:run).
|
58
|
+
with(controller: 'autopromote', role: 'PASSIVE').
|
59
|
+
returns('controllerRole' => 'PASSIVE')
|
60
|
+
role = Girdle::Controller.autopromote(:passive)
|
61
|
+
role.must_equal 'PASSIVE'
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
describe Griddle::Grid do
|
4
|
+
|
5
|
+
it 'must have id attribute' do
|
6
|
+
grid = Griddle::Grid.new(123)
|
7
|
+
grid.id.must_equal 123
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'must retrieve list identifiers of all logical grids' do
|
11
|
+
Griddle.expects(:run).with(grid: 'list').returns([1,2,3])
|
12
|
+
list = Griddle::Grid.list
|
13
|
+
list.must_equal [1,2,3]
|
14
|
+
end
|
15
|
+
|
16
|
+
describe 'a grid' do
|
17
|
+
|
18
|
+
before do
|
19
|
+
@grid = Griddle::Grid.new(123)
|
20
|
+
@attributes = {
|
21
|
+
'name' => 'name',
|
22
|
+
'gridMegahertz' => '0',
|
23
|
+
'isDefault' => 'YES'
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'must retrieve attributes' do
|
28
|
+
Griddle.expects(:run).with(grid: 'attributes', gid: 123).returns('gridAttributes' => @attributes)
|
29
|
+
@grid.attributes.must_equal @attributes
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'must retrieve name' do
|
33
|
+
@grid.expects(:attributes).returns(@attributes)
|
34
|
+
@grid.name.must_equal 'name'
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'must retrieve megahertz' do
|
38
|
+
@grid.expects(:attributes).returns(@attributes)
|
39
|
+
@grid.megahertz.must_equal '0'
|
40
|
+
end
|
41
|
+
|
42
|
+
describe '#is_default' do
|
43
|
+
|
44
|
+
it 'must be true when isDefault is YES' do
|
45
|
+
@grid.expects(:attributes).returns(@attributes)
|
46
|
+
@grid.is_default?.must_equal true
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'must be false when isDefault is NO' do
|
50
|
+
attributes = @attributes.merge('isDefault' => 'NO')
|
51
|
+
@grid.expects(:attributes).returns(attributes)
|
52
|
+
@grid.is_default?.must_equal false
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,178 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
describe Girdle::Job do
|
4
|
+
|
5
|
+
it 'must have an id attribute' do
|
6
|
+
job = Girdle::Job.new(123)
|
7
|
+
job.id.must_equal 123
|
8
|
+
end
|
9
|
+
|
10
|
+
describe 'new jobs' do
|
11
|
+
it 'must submit asynchronous job and return an id' do
|
12
|
+
Girdle.expects(:run).with(job: 'submit', cmd: '/bin/echo hello').
|
13
|
+
returns('jobIdentifier' => '123')
|
14
|
+
id = Girdle::Job.submit('/bin/echo hello')
|
15
|
+
id.must_equal '123'
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'must run and retrieve result synchronously' do
|
19
|
+
Girdle.expects(:run).with(job: 'run', cmd: '/bin/echo hello').
|
20
|
+
returns('hello')
|
21
|
+
result = Girdle::Job.run('/bin/echo hello')
|
22
|
+
result.must_equal 'hello'
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'must submit batch file and return an id' do
|
26
|
+
plist = Girdle::Specification.new(
|
27
|
+
name: 'specification name',
|
28
|
+
notification_email: 'email@example.com',
|
29
|
+
tasks: [
|
30
|
+
Girdle::Task.new(
|
31
|
+
name: 'task name',
|
32
|
+
command: '/bin/echo',
|
33
|
+
arguments: ['hello'],
|
34
|
+
depends_on: ['another task']
|
35
|
+
)
|
36
|
+
]
|
37
|
+
).to_plist
|
38
|
+
Girdle.expects(:run_batch).
|
39
|
+
with(plist, job: 'batch').
|
40
|
+
returns('jobIdentifier' => '123')
|
41
|
+
id = Girdle::Job.batch(plist)
|
42
|
+
id.must_equal '123'
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'must retrieve list of jobs' do
|
47
|
+
Girdle.expects(:run).with(job: 'list').returns('jobList' => %w{1 2 3})
|
48
|
+
list = Girdle::Job.list
|
49
|
+
list.must_equal %w{1 2 3}
|
50
|
+
end
|
51
|
+
|
52
|
+
describe 'a job' do
|
53
|
+
|
54
|
+
before do
|
55
|
+
@job = Girdle::Job.new(123)
|
56
|
+
end
|
57
|
+
|
58
|
+
describe 'attributes' do
|
59
|
+
|
60
|
+
before do
|
61
|
+
@attributes = {
|
62
|
+
'activeCPUPower' => '0',
|
63
|
+
'dateNow' => DateTime.parse('2011-08-18 11:20:43 +0000'),
|
64
|
+
'dateStarted' => DateTime.parse('2011-07-15 10:05:18 +0000'),
|
65
|
+
'dateStopped' => DateTime.parse('2011-07-15 10:07:46 +0000'),
|
66
|
+
'dateSubmitted' => DateTime.parse('2011-07-15 10:02:53 +0000'),
|
67
|
+
'jobStatus' => 'Finished',
|
68
|
+
'name' => 'Untitled',
|
69
|
+
'percentDone' => 100.0,
|
70
|
+
'taskCount' => '13',
|
71
|
+
'undoneTaskCount' => '1'
|
72
|
+
}
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'must retrieve attributes' do
|
76
|
+
Girdle.expects(:run).
|
77
|
+
with(job: 'attributes', id: 123).
|
78
|
+
returns('jobAttributes' => @attributes)
|
79
|
+
@job.attributes.must_equal @attributes
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'must retrieve active cpu power' do
|
83
|
+
@job.expects(:attributes).returns(@attributes)
|
84
|
+
@job.active_cpu_power.must_equal 0
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'must retrieve date now' do
|
88
|
+
@job.expects(:attributes).returns(@attributes)
|
89
|
+
@job.date_now.must_equal DateTime.parse('2011-08-18 11:20:43 +0000')
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'must retrieve date started' do
|
93
|
+
@job.expects(:attributes).returns(@attributes)
|
94
|
+
@job.date_started.must_equal DateTime.parse('2011-07-15 10:05:18 +0000')
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'must retrieve date stopped' do
|
98
|
+
@job.expects(:attributes).returns(@attributes)
|
99
|
+
@job.date_stopped.must_equal DateTime.parse('2011-07-15 10:07:46 +0000')
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'must retrieve date submitted' do
|
103
|
+
@job.expects(:attributes).returns(@attributes)
|
104
|
+
@job.date_submitted.must_equal DateTime.parse('2011-07-15 10:02:53 +0000')
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'must retrieve status' do
|
108
|
+
@job.expects(:attributes).returns(@attributes)
|
109
|
+
@job.status.must_equal :finished
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'must retrieve name' do
|
113
|
+
@job.expects(:attributes).returns(@attributes)
|
114
|
+
@job.name.must_equal 'Untitled'
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'must retrieve percent done' do
|
118
|
+
@job.expects(:attributes).returns(@attributes)
|
119
|
+
@job.percent_done.must_equal 100
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'must retrieve task count' do
|
123
|
+
@job.expects(:attributes).returns(@attributes)
|
124
|
+
@job.task_count.must_equal 13
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'must retrieve undone task count' do
|
128
|
+
@job.expects(:attributes).returns(@attributes)
|
129
|
+
@job.undone_task_count.must_equal 1
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'must retrieve results' do
|
134
|
+
Girdle.expects(:run).with(job: 'results', id: 123).returns('results')
|
135
|
+
@job.results.must_equal 'results'
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'must retrieve specification' do
|
139
|
+
Girdle.expects(:run).
|
140
|
+
with(job: 'specification', id: 123).
|
141
|
+
returns('jobSpecification' => Hash.new)
|
142
|
+
@job.specification.must_equal Hash.new
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'must retrieve log' do
|
146
|
+
Girdle.expects(:run).with(job: 'log', id: 123).returns('log')
|
147
|
+
@job.log.must_equal 'log'
|
148
|
+
end
|
149
|
+
|
150
|
+
describe 'status' do
|
151
|
+
|
152
|
+
it 'must stop, but don\'t delete' do
|
153
|
+
Girdle.expects(:run).with(job: 'stop', id: 123)
|
154
|
+
@job.stop
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'must suspend' do
|
158
|
+
Girdle.expects(:run).with(job: 'suspend', id: 123)
|
159
|
+
@job.suspend
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'must resume' do
|
163
|
+
Girdle.expects(:run).with(job: 'resume', id: 123)
|
164
|
+
@job.resume
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'must stop and delete' do
|
168
|
+
Girdle.expects(:run).with(job: 'delete', id: 123)
|
169
|
+
@job.delete
|
170
|
+
end
|
171
|
+
|
172
|
+
it 'must restart a running or stopped job' do
|
173
|
+
Girdle.expects(:run).with(job: 'restart', id: 123)
|
174
|
+
@job.restart
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
def plist
|
4
|
+
<<-EOS
|
5
|
+
<?xml version="1.0"?>
|
6
|
+
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
7
|
+
<plist version="1.0">
|
8
|
+
<array>
|
9
|
+
<key>name</key>
|
10
|
+
<string>specification name</string>
|
11
|
+
<key>notificationEmail</key>
|
12
|
+
<string>email@example.com</string>
|
13
|
+
<key>taskSpecifications</key>
|
14
|
+
<dict>
|
15
|
+
<key>name</key>
|
16
|
+
<string>task name</string>
|
17
|
+
<dict>
|
18
|
+
<key>arguments</key>
|
19
|
+
<array>
|
20
|
+
<string>hello</string>
|
21
|
+
</array>
|
22
|
+
<key>command</key>
|
23
|
+
<string>/bin/echo</string>
|
24
|
+
<key>dependsOnTasks</key>
|
25
|
+
<array>
|
26
|
+
<string>another task</string>
|
27
|
+
</array>
|
28
|
+
</dict>
|
29
|
+
</dict>
|
30
|
+
</array>
|
31
|
+
</plist>
|
32
|
+
EOS
|
33
|
+
end
|
34
|
+
|
35
|
+
describe Girdle::Specification do
|
36
|
+
|
37
|
+
before do
|
38
|
+
@spec = Girdle::Specification.new(
|
39
|
+
name: 'specification name',
|
40
|
+
notification_email: 'email@example.com',
|
41
|
+
tasks: [
|
42
|
+
Girdle::Task.new(
|
43
|
+
name: 'task name',
|
44
|
+
command: '/bin/echo',
|
45
|
+
arguments: ['hello'],
|
46
|
+
depends_on: ['another task']
|
47
|
+
)
|
48
|
+
]
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'must have name, notification_email, tasks and depends_on accessors' do
|
53
|
+
@spec.name.must_equal 'specification name'
|
54
|
+
@spec.notification_email.must_equal 'email@example.com'
|
55
|
+
@spec.tasks.size.must_equal 1
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'must append tasks' do
|
59
|
+
@spec.tasks.size.must_equal 1
|
60
|
+
@spec.tasks << Girdle::Task.new
|
61
|
+
@spec.tasks.size.must_equal 2
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'must render itself as a plist' do
|
65
|
+
@spec.to_plist.must_equal plist
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
describe Girdle::Task do
|
4
|
+
|
5
|
+
it 'must have name, command, arguments and depends_on attributes' do
|
6
|
+
task = Girdle::Task.new(
|
7
|
+
name: 'name',
|
8
|
+
command: '/bin/echo',
|
9
|
+
arguments: [],
|
10
|
+
depends_on: []
|
11
|
+
)
|
12
|
+
task.name.must_equal 'name'
|
13
|
+
task.command.must_equal '/bin/echo'
|
14
|
+
task.arguments.must_equal []
|
15
|
+
task.depends_on.must_equal []
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
end
|
data/spec/girdle_spec.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
def plist
|
4
|
+
<<-EOS
|
5
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
6
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
7
|
+
<plist version="1.0">
|
8
|
+
<dict>
|
9
|
+
</dict>
|
10
|
+
</plist>
|
11
|
+
EOS
|
12
|
+
end
|
13
|
+
|
14
|
+
describe Girdle do
|
15
|
+
|
16
|
+
describe '::run' do
|
17
|
+
|
18
|
+
it 'must call xgrid with default options' do
|
19
|
+
Girdle.expects(:`).
|
20
|
+
with('/usr/bin/xgrid -hostname localhost -auth None -format xml -failover YES -autocopy YES').
|
21
|
+
returns(plist)
|
22
|
+
Girdle.run
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'must format commands and arguments' do
|
26
|
+
Girdle.expects(:`).
|
27
|
+
with('/usr/bin/xgrid -hostname localhost -auth None -format xml -failover YES -autocopy YES -job run /bin/echo hello').
|
28
|
+
returns(plist)
|
29
|
+
Girdle.run(job: 'run', cmd: '/bin/echo hello')
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
describe '::run_batch' do
|
35
|
+
|
36
|
+
it 'must pipe xml to xgrid using - argument' do
|
37
|
+
Girdle.expects(:`).
|
38
|
+
with('xml | /usr/bin/xgrid -hostname localhost -auth None -format xml -failover YES -autocopy YES -').
|
39
|
+
returns(plist)
|
40
|
+
Girdle.run_batch('xml')
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,160 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: girdle
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jamie Hodge
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-08-18 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: &70331454389380 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70331454389380
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: guard
|
27
|
+
requirement: &70331454412740 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70331454412740
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: guard-minitest
|
38
|
+
requirement: &70331454412320 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70331454412320
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rb-fsevent
|
49
|
+
requirement: &70331454411900 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70331454411900
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: growl_notify
|
60
|
+
requirement: &70331454411480 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *70331454411480
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: mocha
|
71
|
+
requirement: &70331454411060 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *70331454411060
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: nokogiri
|
82
|
+
requirement: &70331454410640 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
type: :runtime
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: *70331454410640
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: nokogiri-plist
|
93
|
+
requirement: &70331454410220 !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ! '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
type: :runtime
|
100
|
+
prerelease: false
|
101
|
+
version_requirements: *70331454410220
|
102
|
+
description: An Xgrid client
|
103
|
+
email:
|
104
|
+
- jamiehodge@me.com
|
105
|
+
executables: []
|
106
|
+
extensions: []
|
107
|
+
extra_rdoc_files: []
|
108
|
+
files:
|
109
|
+
- .gitignore
|
110
|
+
- Gemfile
|
111
|
+
- Guardfile
|
112
|
+
- README.markdown
|
113
|
+
- Rakefile
|
114
|
+
- girdle.gemspec
|
115
|
+
- lib/girdle.rb
|
116
|
+
- lib/girdle/controller.rb
|
117
|
+
- lib/girdle/grid.rb
|
118
|
+
- lib/girdle/job.rb
|
119
|
+
- lib/girdle/specification.rb
|
120
|
+
- lib/girdle/task.rb
|
121
|
+
- lib/girdle/version.rb
|
122
|
+
- spec/girdle/controller_spec.rb
|
123
|
+
- spec/girdle/grid_spec.rb
|
124
|
+
- spec/girdle/job_spec.rb
|
125
|
+
- spec/girdle/specification_spec.rb
|
126
|
+
- spec/girdle/task_spec.rb
|
127
|
+
- spec/girdle_spec.rb
|
128
|
+
- spec/spec_helper.rb
|
129
|
+
homepage: http://github.com/jamiehodge/girdle
|
130
|
+
licenses: []
|
131
|
+
post_install_message:
|
132
|
+
rdoc_options: []
|
133
|
+
require_paths:
|
134
|
+
- lib
|
135
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
136
|
+
none: false
|
137
|
+
requirements:
|
138
|
+
- - ! '>='
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: '0'
|
141
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
142
|
+
none: false
|
143
|
+
requirements:
|
144
|
+
- - ! '>='
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0'
|
147
|
+
requirements: []
|
148
|
+
rubyforge_project:
|
149
|
+
rubygems_version: 1.8.5
|
150
|
+
signing_key:
|
151
|
+
specification_version: 3
|
152
|
+
summary: A client for submitting and managing Xgrid jobs
|
153
|
+
test_files:
|
154
|
+
- spec/girdle/controller_spec.rb
|
155
|
+
- spec/girdle/grid_spec.rb
|
156
|
+
- spec/girdle/job_spec.rb
|
157
|
+
- spec/girdle/specification_spec.rb
|
158
|
+
- spec/girdle/task_spec.rb
|
159
|
+
- spec/girdle_spec.rb
|
160
|
+
- spec/spec_helper.rb
|