girdle 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'http://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in girdle.gemspec
4
+ gemspec
5
+
6
+ gem 'nokogiri'
7
+ gem 'nokogiri-plist'
@@ -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
@@ -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.
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require 'bundler/gem_tasks'
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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,3 @@
1
+ module Girdle
2
+ VERSION = "0.0.1"
3
+ 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
@@ -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
+
@@ -0,0 +1,7 @@
1
+ require 'minitest/autorun'
2
+
3
+ require 'bundler'
4
+ Bundler.require(:development)
5
+
6
+
7
+ require_relative '../lib/girdle'
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