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.
@@ -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