priteau-vizir 0.2.2 → 0.2.3
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/Rakefile +4 -2
- data/VERSION +1 -1
- data/bin/vizir +26 -96
- data/lib/vizir.rb +109 -0
- data/test/test_helper.rb +4 -1
- data/test/test_vizir.rb +99 -0
- data/vizir.gemspec +5 -4
- metadata +5 -5
- data/test/vizir_test.rb +0 -17
data/Rakefile
CHANGED
@@ -9,6 +9,7 @@ begin
|
|
9
9
|
gem.email = "pierre.riteau@gmail.com"
|
10
10
|
gem.homepage = "http://github.com/priteau/vizir"
|
11
11
|
gem.authors = ["Pierre Riteau"]
|
12
|
+
gem.rubyforge_project = "vizir"
|
12
13
|
gem.add_dependency "eventmachine"
|
13
14
|
gem.add_dependency "growlnotifier"
|
14
15
|
gem.add_dependency "json"
|
@@ -17,6 +18,7 @@ begin
|
|
17
18
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
18
19
|
end
|
19
20
|
|
21
|
+
Jeweler::RubyforgeTasks.new
|
20
22
|
rescue LoadError
|
21
23
|
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
22
24
|
end
|
@@ -24,7 +26,7 @@ end
|
|
24
26
|
require 'rake/testtask'
|
25
27
|
Rake::TestTask.new(:test) do |test|
|
26
28
|
test.libs << 'lib' << 'test'
|
27
|
-
test.pattern = 'test
|
29
|
+
test.pattern = 'test/**/test_*.rb'
|
28
30
|
test.verbose = true
|
29
31
|
end
|
30
32
|
|
@@ -32,7 +34,7 @@ begin
|
|
32
34
|
require 'rcov/rcovtask'
|
33
35
|
Rcov::RcovTask.new do |test|
|
34
36
|
test.libs << 'test'
|
35
|
-
test.pattern = 'test
|
37
|
+
test.pattern = 'test/**/test_*.rb'
|
36
38
|
test.verbose = true
|
37
39
|
end
|
38
40
|
rescue LoadError
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.3
|
data/bin/vizir
CHANGED
@@ -4,43 +4,13 @@ $:.unshift File.join(File.dirname(__FILE__), "..", "lib")
|
|
4
4
|
|
5
5
|
require 'eventmachine'
|
6
6
|
require 'growl'
|
7
|
-
require 'json'
|
8
7
|
require 'net/ssh/gateway'
|
9
8
|
require 'optparse'
|
10
9
|
require 'rest_client'
|
11
10
|
require 'vizir'
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
REFRESH_TIME = 3600
|
16
|
-
IGNORE_SITES = ['grenoble-exp', 'grenoble-ext', 'grenoble-obs', 'luxembourg', 'portoalegre']
|
17
|
-
|
18
|
-
def usage
|
19
|
-
puts 'usage: vizir [ -h | --help ] [ -l | --login login_name ]'
|
20
|
-
exit 1
|
21
|
-
end
|
22
|
-
|
23
|
-
def get(api, uri)
|
24
|
-
begin
|
25
|
-
return JSON.parse(api[uri + '?structure=simple'].get(:accept => 'application/json'))
|
26
|
-
rescue RestClient::RequestTimeout => e
|
27
|
-
# This should really be elsewhere, but will do for now
|
28
|
-
# Were we querying a specific site? If yes, remove it from $sites
|
29
|
-
if uri =~ /\/sites\/(\w+)/
|
30
|
-
$sites.delete_if { |site| site['site'] == "#{$1}" }
|
31
|
-
else
|
32
|
-
raise e
|
33
|
-
end
|
34
|
-
rescue => e
|
35
|
-
if e.respond_to?('http_code')
|
36
|
-
puts "Error: #{e.http_code}:\n #{e.response.body}"
|
37
|
-
return nil
|
38
|
-
else
|
39
|
-
puts e.inspect
|
40
|
-
exit 1
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
12
|
+
$alert_period = 60
|
13
|
+
$refresh_period = 3600
|
44
14
|
|
45
15
|
def setup_ssh_tunnel
|
46
16
|
gateway = Net::SSH::Gateway.new('access.grenoble.grid5000.fr', $login)
|
@@ -58,87 +28,47 @@ def setup_growl
|
|
58
28
|
end
|
59
29
|
|
60
30
|
def notify_via_growl(jobid, site_name, time, time_unit)
|
61
|
-
$growl.notify('Job ending soon', 'OAR job terminating soon', "Job #{jobid} in #{site_name} ending in #{time} #{time_unit}.")
|
62
|
-
end
|
63
|
-
|
64
|
-
def get_remaining_time(time)
|
65
|
-
return (time - Time.now).round
|
31
|
+
$growl.notify('Job ending soon', 'OAR job terminating soon', "Job #{jobid} in #{site_name} ending in #{time} #{time_unit}.", :sticky => true)
|
66
32
|
end
|
67
33
|
|
68
34
|
$login = nil
|
69
|
-
opts = OptionParser.new
|
70
|
-
opts.on('-h', '--help') { usage }
|
71
|
-
opts.on('-l', '--login STRING', String) { |str| $login = str }
|
72
|
-
opts.parse(ARGV)
|
73
|
-
|
74
|
-
if $login == nil
|
75
|
-
usage
|
76
|
-
end
|
77
35
|
|
78
|
-
|
79
|
-
|
80
|
-
|
36
|
+
opts = OptionParser.new do |opts|
|
37
|
+
opts.banner = "Usage: vizir [options]"
|
38
|
+
opts.separator("")
|
81
39
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
break if jobs == nil
|
88
|
-
jobs.each do |job|
|
89
|
-
if job['owner'] == $login
|
90
|
-
job_details = get(api, "#{job['uri']}")
|
91
|
-
break if job_details == nil
|
92
|
-
if job_details['jobType'] == 'INTERACTIVE'
|
93
|
-
jobid = job_details['Job_Id']
|
94
|
-
|
95
|
-
# If we don't yet know the job, record it in $jobs
|
96
|
-
if $jobs[jobid].nil?
|
97
|
-
$jobs[jobid] = Vizir::Job.new(jobid, Time.at(Integer(job_details['startTime']) + Integer(job_details['walltime'])), site_name.capitalize)
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
40
|
+
opts.separator("Options:")
|
41
|
+
opts.on('-a', '--alert-period TIME', Integer, "Job alert period (seconds), default: #{$alert_period}") { |t| $alert_period = t }
|
42
|
+
opts.on('-h', '--help', 'Print help') do
|
43
|
+
puts opts
|
44
|
+
exit
|
103
45
|
end
|
46
|
+
opts.on('-l', '--login LOGIN', String, "User login on Grid\'5000") { |str| $login = str }
|
47
|
+
opts.on('-m', '--min-job-time TIME', Integer, "Minimum job time (seconds), default: #{$refresh_period}") { |t| $refresh_period = t }
|
104
48
|
end
|
105
49
|
|
106
|
-
|
107
|
-
$jobs.sort{|a,b| a[1].end_time <=> b[1].end_time}.first
|
108
|
-
end
|
50
|
+
opts.parse!(ARGV)
|
109
51
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
if remaining_sec < FIRST_ALERT_TIME
|
114
|
-
# Check if the job still exists before sending a notification
|
115
|
-
updatedjob = get(api, "/sites/#{job.site_name.downcase}/jobs/#{job.id}")
|
116
|
-
if updatedjob['state'] != 'Running'
|
117
|
-
# Job is not running anymore, remove it from the hash
|
118
|
-
$jobs.delete(jobid)
|
119
|
-
next
|
120
|
-
end
|
121
|
-
if remaining_sec < 0
|
122
|
-
$stderr.puts "Error: negative time"
|
123
|
-
next
|
124
|
-
end
|
125
|
-
remaining_time, remaining_time_unit = Vizir.humanize_time(remaining_sec)
|
126
|
-
notify_via_growl(jobid, job.site_name, remaining_time, remaining_time_unit)
|
127
|
-
end
|
128
|
-
end
|
52
|
+
if $login == nil
|
53
|
+
puts opts
|
54
|
+
exit
|
129
55
|
end
|
130
56
|
|
57
|
+
gateway, port = setup_ssh_tunnel
|
58
|
+
api = Vizir.get_api(apiuri(port))
|
59
|
+
setup_growl
|
60
|
+
|
131
61
|
# Learn the Grid'5000 sites
|
132
62
|
$jobs = Hash.new
|
133
|
-
$sites =
|
63
|
+
$sites = Vizir.learn_sites(api, Vizir::IGNORED_SITES)
|
134
64
|
exit 1 if $sites == nil
|
135
65
|
|
136
|
-
learn_new_jobs(api)
|
137
|
-
alert_jobs(api)
|
66
|
+
Vizir.learn_new_jobs(api)
|
67
|
+
Vizir.alert_jobs(api)
|
138
68
|
|
139
69
|
EventMachine::run {
|
140
|
-
EventMachine::PeriodicTimer.new(
|
141
|
-
EventMachine::PeriodicTimer.new(
|
70
|
+
EventMachine::PeriodicTimer.new($refresh_period) { Vizir.learn_new_jobs(api) }
|
71
|
+
EventMachine::PeriodicTimer.new($alert_period) { Vizir.alert_jobs(api) }
|
142
72
|
}
|
143
73
|
|
144
74
|
gateway.shutdown!
|
data/lib/vizir.rb
CHANGED
@@ -1,4 +1,11 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'restclient'
|
3
|
+
|
1
4
|
module Vizir
|
5
|
+
APIURL = "https://localhost:8080/oargridapi"
|
6
|
+
IGNORED_SITES = ['grenoble-exp', 'grenoble-ext', 'grenoble-obs', 'luxembourg', 'portoalegre']
|
7
|
+
FIRST_ALERT_TIME = 600
|
8
|
+
|
2
9
|
def Vizir.humanize_time(time)
|
3
10
|
fail "Can't humanize negative period" if time < 0
|
4
11
|
|
@@ -17,6 +24,90 @@ module Vizir
|
|
17
24
|
return remaining_time, remaining_time_unit
|
18
25
|
end
|
19
26
|
|
27
|
+
def Vizir.get_remaining_time(end_time, now)
|
28
|
+
return (end_time - now).round
|
29
|
+
end
|
30
|
+
|
31
|
+
def Vizir.get(api, uri)
|
32
|
+
begin
|
33
|
+
return JSON.parse(api[uri + '?structure=simple'].get(:accept => 'application/json'))
|
34
|
+
rescue RestClient::RequestTimeout => e
|
35
|
+
# This should really be elsewhere, but will do for now
|
36
|
+
# Were we querying a specific site? If yes, remove it from $sites
|
37
|
+
if uri =~ /\/sites\/(\w+)/
|
38
|
+
$sites.delete_if { |site| site['site'] == "#{$1}" }
|
39
|
+
return nil
|
40
|
+
else
|
41
|
+
raise e
|
42
|
+
end
|
43
|
+
rescue => e
|
44
|
+
if e.respond_to?('http_code')
|
45
|
+
puts "Error: #{e.http_code}:\n #{e.response.body}"
|
46
|
+
return nil
|
47
|
+
else
|
48
|
+
puts e.inspect
|
49
|
+
exit 1
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def Vizir.learn_sites(api, ignored_sites)
|
55
|
+
return get(api, '/sites').delete_if { |hash| ignored_sites.include?(hash["site"]) }
|
56
|
+
end
|
57
|
+
|
58
|
+
def Vizir.get_api(uri)
|
59
|
+
return RestClient::Resource.new(uri, :timeout => 15)
|
60
|
+
end
|
61
|
+
|
62
|
+
def Vizir.learn_new_jobs_on_site(api, site)
|
63
|
+
site_name = site['site']
|
64
|
+
jobs = Vizir.get(api, "#{site['uri']}/jobs")
|
65
|
+
return if jobs.nil?
|
66
|
+
jobs.each do |job|
|
67
|
+
if job['owner'] == $login
|
68
|
+
job_details = Vizir.get(api, "#{job['uri']}")
|
69
|
+
break if job_details == nil
|
70
|
+
if job_details['jobType'] == 'INTERACTIVE'
|
71
|
+
jobid = job_details['Job_Id']
|
72
|
+
# If we don't yet know the job, record it in $jobs
|
73
|
+
if $jobs[jobid].nil?
|
74
|
+
$jobs[jobid] = Vizir::Job.new(jobid, Time.at(Integer(job_details['startTime']) + Integer(job_details['walltime'])), site_name.capitalize)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def Vizir.learn_new_jobs(api)
|
82
|
+
$sites.each do |site|
|
83
|
+
Vizir.learn_new_jobs_on_site(api, site)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def Vizir.first_ending_job
|
88
|
+
$jobs.sort{|a,b| a[1].end_time <=> b[1].end_time}.first
|
89
|
+
end
|
90
|
+
|
91
|
+
def Vizir.alert_jobs(api)
|
92
|
+
$jobs.each do |jobid, job|
|
93
|
+
if job.should_be_ending?
|
94
|
+
# Check if the job still exists before sending a notification
|
95
|
+
if job.is_ended?(api)
|
96
|
+
# Job is not running anymore, remove it from the hash
|
97
|
+
$jobs.delete(jobid)
|
98
|
+
next
|
99
|
+
end
|
100
|
+
remaining_sec = Vizir.get_remaining_time(job.end_time, Time.now)
|
101
|
+
if remaining_sec < 0
|
102
|
+
$stderr.puts "Error: negative time"
|
103
|
+
next
|
104
|
+
end
|
105
|
+
remaining_time, remaining_time_unit = Vizir.humanize_time(remaining_sec)
|
106
|
+
notify_via_growl(jobid, job.site_name, remaining_time, remaining_time_unit)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
20
111
|
class Job
|
21
112
|
attr_reader :id, :end_time, :site_name
|
22
113
|
|
@@ -25,5 +116,23 @@ module Vizir
|
|
25
116
|
@end_time = end_time
|
26
117
|
@site_name = site_name
|
27
118
|
end
|
119
|
+
|
120
|
+
def Job.create_from_json(json, site_name)
|
121
|
+
return Job.new(json['Job_Id'], Time.at(Integer(json['startTime']) + Integer(json['walltime'])), site_name.capitalize)
|
122
|
+
end
|
123
|
+
|
124
|
+
def fetch_details(api)
|
125
|
+
return Vizir.get(api, "/sites/#{@site_name.downcase}/jobs/#{@id}")
|
126
|
+
end
|
127
|
+
|
128
|
+
def should_be_ending?(time=Time.now())
|
129
|
+
return Vizir.get_remaining_time(self.end_time, time) <= Vizir::FIRST_ALERT_TIME
|
130
|
+
end
|
131
|
+
|
132
|
+
def is_ended?(api)
|
133
|
+
updatedjob = self.fetch_details(api)
|
134
|
+
return updatedjob['state'] != 'Running'
|
135
|
+
end
|
136
|
+
|
28
137
|
end
|
29
138
|
end
|
data/test/test_helper.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'test/unit'
|
3
|
+
require 'shoulda'
|
4
|
+
|
5
|
+
require 'fakeweb'
|
3
6
|
|
4
|
-
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
5
7
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
8
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
6
9
|
require 'vizir'
|
7
10
|
|
8
11
|
class Test::Unit::TestCase
|
data/test/test_vizir.rb
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class VizirTest < Test::Unit::TestCase
|
4
|
+
TIMES = [
|
5
|
+
[0, [0, "second"]],
|
6
|
+
[1, [1, "second"]],
|
7
|
+
[30, [30, "seconds"]],
|
8
|
+
[59, [59, "seconds"]],
|
9
|
+
[60, [1, "minute"]],
|
10
|
+
[119, [1, "minute"]],
|
11
|
+
[120, [2, "minutes"]]
|
12
|
+
]
|
13
|
+
def test_humanize_time
|
14
|
+
TIMES.each do |seconds, result|
|
15
|
+
assert_equal(result, Vizir.humanize_time(seconds))
|
16
|
+
end
|
17
|
+
e = assert_raise(RuntimeError) { Vizir.humanize_time(-1) }
|
18
|
+
assert_equal("Can't humanize negative period", e.message)
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_learn_sites
|
22
|
+
FakeWeb.allow_net_connect = false
|
23
|
+
o = [
|
24
|
+
{
|
25
|
+
"site" => "nancy",
|
26
|
+
"uri" => "/sites/nancy"
|
27
|
+
},
|
28
|
+
{
|
29
|
+
"site" => "rennes",
|
30
|
+
"uri" => "/sites/rennes"
|
31
|
+
},
|
32
|
+
{
|
33
|
+
"site" => "luxembourg",
|
34
|
+
"uri" => "/sites/luxembourg"
|
35
|
+
}]
|
36
|
+
json = JSON.generate(o)
|
37
|
+
FakeWeb.register_uri(:get, "#{Vizir::APIURL}/sites?structure=simple", :string => json)
|
38
|
+
api = Vizir.get_api(Vizir::APIURL)
|
39
|
+
sites = o.delete_if { |hash| hash["site"] == "luxembourg" }
|
40
|
+
ignored_sites = ["luxembourg", "portoalegre"]
|
41
|
+
assert_equal(sites, Vizir.learn_sites(api, ignored_sites))
|
42
|
+
end
|
43
|
+
|
44
|
+
context "A Job instance" do
|
45
|
+
setup do
|
46
|
+
@job_endtime = Time.at(123456789)
|
47
|
+
@job = Vizir::Job.new('1234', @job_endtime, 'Rennes')
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'ending in FIRST_ALERT_TIME seconds' do
|
51
|
+
setup do
|
52
|
+
@now = Time.at(Integer(@job_endtime) - Integer(Vizir::FIRST_ALERT_TIME))
|
53
|
+
end
|
54
|
+
|
55
|
+
should 'be considered as ending soon' do
|
56
|
+
assert_equal true, @job.should_be_ending?(@now)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'ending in more than FIRST_ALERT_TIME seconds' do
|
61
|
+
setup do
|
62
|
+
@now = Time.at(Integer(@job_endtime) - Integer(Vizir::FIRST_ALERT_TIME + 1))
|
63
|
+
end
|
64
|
+
|
65
|
+
should 'not be considered as ending soon' do
|
66
|
+
assert_equal false, @job.should_be_ending?(@now)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'A site-specific query' do
|
72
|
+
setup do
|
73
|
+
@uri = "#{Vizir::APIURL}/sites/rennes/jobs?structure=simple"
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'which timeouts' do
|
77
|
+
setup do
|
78
|
+
FakeWeb.register_uri(:get, @uri, :exception => Timeout::Error)
|
79
|
+
@api = Vizir.get_api(Vizir::APIURL)
|
80
|
+
end
|
81
|
+
|
82
|
+
should 'remove the site from the sites list' do
|
83
|
+
$sites = [
|
84
|
+
{
|
85
|
+
"site" => "nancy",
|
86
|
+
"uri" => "/sites/nancy"
|
87
|
+
},
|
88
|
+
{
|
89
|
+
"site" => "rennes",
|
90
|
+
"uri" => "/sites/rennes"
|
91
|
+
}
|
92
|
+
]
|
93
|
+
Vizir.learn_new_jobs_on_site(@api, $sites[1])
|
94
|
+
assert_equal [{ "site" => "nancy", "uri" => "/sites/nancy" }], $sites
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
data/vizir.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{vizir}
|
5
|
-
s.version = "0.2.
|
5
|
+
s.version = "0.2.3"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Pierre Riteau"]
|
9
|
-
s.date = %q{2009-06-
|
9
|
+
s.date = %q{2009-06-18}
|
10
10
|
s.default_executable = %q{vizir}
|
11
11
|
s.email = %q{pierre.riteau@gmail.com}
|
12
12
|
s.executables = ["vizir"]
|
@@ -24,18 +24,19 @@ Gem::Specification.new do |s|
|
|
24
24
|
"bin/vizir",
|
25
25
|
"lib/vizir.rb",
|
26
26
|
"test/test_helper.rb",
|
27
|
-
"test/
|
27
|
+
"test/test_vizir.rb",
|
28
28
|
"vizir.gemspec"
|
29
29
|
]
|
30
30
|
s.has_rdoc = true
|
31
31
|
s.homepage = %q{http://github.com/priteau/vizir}
|
32
32
|
s.rdoc_options = ["--charset=UTF-8"]
|
33
33
|
s.require_paths = ["lib"]
|
34
|
+
s.rubyforge_project = %q{vizir}
|
34
35
|
s.rubygems_version = %q{1.3.1}
|
35
36
|
s.summary = %q{Growl notifications for Grid'5000 jobs}
|
36
37
|
s.test_files = [
|
37
38
|
"test/test_helper.rb",
|
38
|
-
"test/
|
39
|
+
"test/test_vizir.rb"
|
39
40
|
]
|
40
41
|
|
41
42
|
if s.respond_to? :specification_version then
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: priteau-vizir
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pierre Riteau
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-06-
|
12
|
+
date: 2009-06-18 00:00:00 -07:00
|
13
13
|
default_executable: vizir
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -81,7 +81,7 @@ files:
|
|
81
81
|
- bin/vizir
|
82
82
|
- lib/vizir.rb
|
83
83
|
- test/test_helper.rb
|
84
|
-
- test/
|
84
|
+
- test/test_vizir.rb
|
85
85
|
- vizir.gemspec
|
86
86
|
has_rdoc: true
|
87
87
|
homepage: http://github.com/priteau/vizir
|
@@ -104,11 +104,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
104
104
|
version:
|
105
105
|
requirements: []
|
106
106
|
|
107
|
-
rubyforge_project:
|
107
|
+
rubyforge_project: vizir
|
108
108
|
rubygems_version: 1.2.0
|
109
109
|
signing_key:
|
110
110
|
specification_version: 2
|
111
111
|
summary: Growl notifications for Grid'5000 jobs
|
112
112
|
test_files:
|
113
113
|
- test/test_helper.rb
|
114
|
-
- test/
|
114
|
+
- test/test_vizir.rb
|
data/test/vizir_test.rb
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class VizirTest < Test::Unit::TestCase
|
4
|
-
TIMES = [
|
5
|
-
[1, [1, "second"]],
|
6
|
-
[30, [30, "seconds"]],
|
7
|
-
[59, [59, "seconds"]],
|
8
|
-
[60, [1, "minute"]],
|
9
|
-
[120, [2, "minutes"]]
|
10
|
-
]
|
11
|
-
def test_humanize_time
|
12
|
-
TIMES.each do |seconds, result|
|
13
|
-
assert_equal(result, Vizir.humanize_time(seconds))
|
14
|
-
end
|
15
|
-
assert_raise(RuntimeError) { Vizir.humanize_time(-1) }
|
16
|
-
end
|
17
|
-
end
|