abundance 1.2.3 → 1.2.4
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/abundance.rb +3 -3
- data/lib/garden.rb +0 -2
- data/lib/garden_cycles.rb +43 -35
- data/lib/garden_rows.rb +24 -13
- data/lib/gardener.rb +6 -7
- data/lib/toolshed.rb +7 -7
- data/test/tc_burst.rb +84 -0
- data/test/ts_abundance.rb +2 -1
- metadata +3 -2
data/lib/abundance.rb
CHANGED
@@ -2,10 +2,10 @@
|
|
2
2
|
# Based on the low maintenance Gardener,Garden,Seed natural design pattern.
|
3
3
|
#
|
4
4
|
# Its for:
|
5
|
-
# *
|
5
|
+
# * running otherwise blocking loops in a non-blocking fashion
|
6
6
|
# * a simple abstraction for loopback communication with a forked execution
|
7
7
|
# * concurrent batch processing
|
8
|
-
# * scaling process intensive computations
|
8
|
+
# * scaling process intensive computations for SMP execution
|
9
9
|
#
|
10
10
|
# And not:
|
11
11
|
# * a replacement for Thread.new invocations
|
@@ -14,7 +14,7 @@
|
|
14
14
|
# Its initial implementation uses:
|
15
15
|
# * pure ruby
|
16
16
|
# * standard forks as mean to parallel non-blocking execution
|
17
|
-
# * fast
|
17
|
+
# * fast loopback sockets for process fork communication.
|
18
18
|
# * serialization friendly communication with process forks
|
19
19
|
# * a tier queuing fork, as a packet control middle man between process forks and the non-blocking process client
|
20
20
|
# * an elemental namespace: a process queue, named the Garden, with concurrent workers, named Rows, all this getting orchestrated by a Gardener.
|
data/lib/garden.rb
CHANGED
data/lib/garden_cycles.rb
CHANGED
@@ -5,7 +5,7 @@ class Garden
|
|
5
5
|
module Cycles
|
6
6
|
|
7
7
|
def set_my_containers
|
8
|
-
@quit = false; @full_crop = false; @do_init = nil; @
|
8
|
+
@quit = false; @full_crop = false; @do_init = nil; @seed_all_message_block = nil; @init_all_crop = []
|
9
9
|
@harvest = []; @rows_socket_paths = []; @init_done = []; @seed_all_done = []; @seed_all_crop = []
|
10
10
|
@seeds = []; @sprouts = []; @crops = []; @id = 0
|
11
11
|
end
|
@@ -13,10 +13,10 @@ class Garden
|
|
13
13
|
def seed_if_row_available
|
14
14
|
catch :fill_rows do
|
15
15
|
loop do
|
16
|
-
if ! @
|
16
|
+
if ! @seed_all_message_block.nil? && ! @rows_socket_paths.empty? && @seed_all_done.size != @seed_all_message_block[1]
|
17
17
|
row_socket_path = @rows_socket_paths.shift
|
18
18
|
unless @seed_all_done.include?( row_socket_path )
|
19
|
-
socket_send(:
|
19
|
+
socket_send([:seed,:all,@seed_all_message_block[2],row_socket_path])
|
20
20
|
@seed_all_done << row_socket_path
|
21
21
|
else
|
22
22
|
@rows_socket_paths << row_socket_path
|
@@ -24,7 +24,7 @@ class Garden
|
|
24
24
|
elsif ! @do_init.nil? && ! @rows_socket_paths.empty? && @init_done.size != @do_init
|
25
25
|
row_socket_path = @rows_socket_paths.shift
|
26
26
|
unless @init_done.include?( row_socket_path )
|
27
|
-
socket_send(:init
|
27
|
+
socket_send([:seed,:init,'init_status',row_socket_path])
|
28
28
|
@init_done << row_socket_path
|
29
29
|
else
|
30
30
|
@rows_socket_paths << row_socket_path
|
@@ -33,11 +33,11 @@ class Garden
|
|
33
33
|
seed = @seeds.shift
|
34
34
|
@sprouts[seed[:id]] = seed
|
35
35
|
row_socket_path = @rows_socket_paths.shift
|
36
|
-
socket_send(:sprout
|
36
|
+
socket_send([:seed,:sprout,seed,row_socket_path])
|
37
37
|
elsif @quit && ! @rows_socket_paths.empty?
|
38
38
|
seed = nil
|
39
39
|
row_socket_path = @rows_socket_paths.shift
|
40
|
-
socket_send(:quit
|
40
|
+
socket_send([:seed,:quit,seed,row_socket_path])
|
41
41
|
else
|
42
42
|
throw :fill_rows
|
43
43
|
end
|
@@ -46,29 +46,42 @@ class Garden
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def place_seed_in_queue(message_block)
|
49
|
-
|
50
|
-
|
49
|
+
case message_block[1]
|
50
|
+
when :one
|
51
|
+
@id += 1; @seeds << {:id => @id , :seed => message_block[2]}
|
52
|
+
socket_send([message_block[0],:garden,@id,message_block[3]])
|
53
|
+
else
|
54
|
+
@seed_all_message_block = Array.new(message_block)
|
55
|
+
end
|
51
56
|
end
|
52
57
|
|
53
58
|
def this_row_is_available(message_block)
|
54
59
|
if @quit
|
55
|
-
message_block
|
60
|
+
message_block = [:row, :quit, nil, message_block[3]]
|
61
|
+
elsif ! @seed_all_message_block.nil? && @seed_all_done.size != @seed_all_message_block[1] && ! @seed_all_done.include?( message_block[3] )
|
62
|
+
message_block = [:row, :all, @seed_all_message_block[2], message_block[3]]
|
63
|
+
@seed_all_done << message_block[3]
|
64
|
+
elsif ! @do_init.nil? && @init_done.size != @do_init && ! @init_done.include?( message_block[3] )
|
65
|
+
message_block = [:row, :init, 'init_status', message_block[3]]
|
66
|
+
@init_done << message_block[3]
|
56
67
|
elsif @seeds.empty?
|
57
|
-
|
68
|
+
@rows_socket_paths << message_block[2]
|
69
|
+
message_block = [:row, :wait, nil, message_block[3]]
|
58
70
|
else
|
59
71
|
seed = @seeds.shift; @sprouts[seed[:id]] = seed
|
72
|
+
message_block = [:row, :sprout, seed, message_block[3]]
|
60
73
|
end
|
61
|
-
socket_send(message_block
|
74
|
+
socket_send(message_block)
|
62
75
|
end
|
63
76
|
|
64
77
|
def save_crop_for(message_block)
|
65
78
|
@sprouts[message_block[2][:id]] = nil
|
66
79
|
@crops[message_block[2][:id]] = message_block[2]
|
67
80
|
if @harvest[message_block[2][:id]]
|
68
|
-
socket_send(message_block[0],:garden,message_block[2], @harvest[message_block[2][:id]][:client_socket_path])
|
81
|
+
socket_send([message_block[0],:garden,message_block[2], @harvest[message_block[2][:id]][:client_socket_path]])
|
69
82
|
@crops[message_block[2][:id]] = @harvest[message_block[2][:id]] = nil
|
70
83
|
elsif @full_crop && @seeds.compact.empty? && @sprouts.compact.empty?
|
71
|
-
socket_send(message_block[0],:garden,@crops.compact,@mem_client_socket_path)
|
84
|
+
socket_send([message_block[0],:garden,@crops.compact,@mem_client_socket_path])
|
72
85
|
@crops.clear; @full_crop = false
|
73
86
|
end
|
74
87
|
end
|
@@ -78,32 +91,32 @@ class Garden
|
|
78
91
|
when :progress
|
79
92
|
value = @crops.size.to_f / (@crops.size + @sprouts.compact.size + @seeds.size)
|
80
93
|
value = 1 if value.nan?; progress = sprintf( "%.2f", value)
|
81
|
-
socket_send(message_block[0],:garden,progress,message_block[3])
|
94
|
+
socket_send([message_block[0],:garden,progress,message_block[3]])
|
82
95
|
when :seed
|
83
|
-
socket_send(message_block[0],:garden,@seeds.size,message_block[3])
|
96
|
+
socket_send([message_block[0],:garden,@seeds.size,message_block[3]])
|
84
97
|
when :sprout
|
85
|
-
socket_send(message_block[0],:garden,@sprouts.compact.size,message_block[3])
|
98
|
+
socket_send([message_block[0],:garden,@sprouts.compact.size,message_block[3]])
|
86
99
|
when :crop
|
87
|
-
socket_send(message_block[0],:garden,@crops.size,message_block[3])
|
100
|
+
socket_send([message_block[0],:garden,@crops.size,message_block[3]])
|
88
101
|
else
|
89
|
-
socket_send(message_block[0],:garden,false,message_block[3])
|
102
|
+
socket_send([message_block[0],:garden,false,message_block[3]])
|
90
103
|
end
|
91
104
|
end
|
92
105
|
|
93
106
|
def harvest_some(message_block)
|
94
107
|
case message_block[2]
|
95
108
|
when :all
|
96
|
-
socket_send(message_block[0],:garden,{:seeds => @seeds, :sprouts => @sprouts.compact, :crops => @crops.compact},message_block[3])
|
109
|
+
socket_send([message_block[0],:garden,{:seeds => @seeds, :sprouts => @sprouts.compact, :crops => @crops.compact},message_block[3]])
|
97
110
|
when :seed
|
98
|
-
socket_send(message_block[0],:garden,@seeds,message_block[3])
|
111
|
+
socket_send([message_block[0],:garden,@seeds,message_block[3]])
|
99
112
|
when :sprout
|
100
|
-
socket_send(message_block[0],:garden,@sprouts.compact,message_block[3])
|
113
|
+
socket_send([message_block[0],:garden,@sprouts.compact,message_block[3]])
|
101
114
|
when :crop
|
102
|
-
socket_send(message_block[0],:garden,@crops.compact,message_block[3])
|
115
|
+
socket_send([message_block[0],:garden,@crops.compact,message_block[3]])
|
103
116
|
@crops.clear
|
104
117
|
when :full_crop
|
105
118
|
if @seeds.compact.empty? && @sprouts.compact.empty?
|
106
|
-
socket_send(message_block[0],:garden,@crops.compact,message_block[3])
|
119
|
+
socket_send([message_block[0],:garden,@crops.compact,message_block[3]])
|
107
120
|
@crops.clear
|
108
121
|
else
|
109
122
|
@full_crop = true
|
@@ -112,13 +125,13 @@ class Garden
|
|
112
125
|
else
|
113
126
|
if message_block[2].is_a? Integer
|
114
127
|
if @crops[message_block[2]]
|
115
|
-
socket_send(message_block[0],:garden,@crops[message_block[2]],message_block[3])
|
128
|
+
socket_send([message_block[0],:garden,@crops[message_block[2]],message_block[3]])
|
116
129
|
@crops[message_block[2]] = nil
|
117
130
|
else
|
118
131
|
@harvest[message_block[2]] = {:client_socket_path => message_block[3]}
|
119
132
|
end
|
120
133
|
else
|
121
|
-
socket_send(message_block[0],:garden,false,message_block[3])
|
134
|
+
socket_send([message_block[0],:garden,false,message_block[3]])
|
122
135
|
end
|
123
136
|
end
|
124
137
|
end
|
@@ -131,21 +144,16 @@ class Garden
|
|
131
144
|
def answer_init_status(message_block)
|
132
145
|
@init_all_crop << message_block[2]
|
133
146
|
if @init_all_crop.size == @do_init
|
134
|
-
socket_send(message_block[0],:garden,@init_all_crop, @init_return[:client_socket_path])
|
147
|
+
socket_send([message_block[0],:garden,@init_all_crop, @init_return[:client_socket_path]])
|
135
148
|
@init_return = Hash.new; @init_done = Array.new; @do_init = nil; @init_all_crop = Array.new
|
136
149
|
end
|
137
150
|
end
|
138
151
|
|
139
|
-
def seed_for_all_rows(message_block)
|
140
|
-
@seed_all = message_block[2]
|
141
|
-
@seed_all_return = {:client_socket_path => message_block[3], :data => []}
|
142
|
-
end
|
143
|
-
|
144
152
|
def special_crop_seed_all(message_block)
|
145
153
|
@seed_all_crop << message_block[2]
|
146
|
-
if @seed_all_crop.size == @
|
147
|
-
socket_send(message_block[0],:garden,@seed_all_crop, @
|
148
|
-
@
|
154
|
+
if @seed_all_crop.size == @seed_all_message_block[1]
|
155
|
+
socket_send([message_block[0],:garden,@seed_all_crop, @seed_all_message_block[3]])
|
156
|
+
@seed_all_message_block = nil; @seed_all_done = Array.new; @seed_all_crop = Array.new
|
149
157
|
end
|
150
158
|
end
|
151
159
|
|
@@ -157,7 +165,7 @@ class Garden
|
|
157
165
|
else
|
158
166
|
@seeds_pid.delete(message_block[2][:pid].to_i)
|
159
167
|
if @seeds_pid.empty?
|
160
|
-
socket_send(:close,:garden,{:seeds => @seeds, :sprouts => @sprouts.compact, :crops => @crops.compact}, @mem_client_socket_path)
|
168
|
+
socket_send([:close,:garden,{:seeds => @seeds, :sprouts => @sprouts.compact, :crops => @crops.compact}, @mem_client_socket_path])
|
161
169
|
exit
|
162
170
|
end
|
163
171
|
end
|
data/lib/garden_rows.rb
CHANGED
@@ -51,32 +51,43 @@ class Garden
|
|
51
51
|
t2 = Thread.new do
|
52
52
|
loop do
|
53
53
|
if $seed.nil?
|
54
|
-
message_block = socket_duplex(:row,:row,my_socket_path)
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
54
|
+
message_block = socket_duplex([:row,:row,my_socket_path,@garden_path])
|
55
|
+
case message_block[1]
|
56
|
+
when :sprout
|
57
|
+
$seed = message_block[2]
|
58
|
+
when :all
|
59
|
+
@seed_all = true
|
60
|
+
$seed = {:id => Process.pid, :seed => message_block[2]}
|
61
|
+
when :wait
|
62
62
|
message_block = socket_recv
|
63
|
-
case message_block[
|
63
|
+
case message_block[1]
|
64
64
|
when :sprout
|
65
65
|
$seed = message_block[2]
|
66
|
-
when :
|
66
|
+
when :all
|
67
67
|
@seed_all = true
|
68
68
|
$seed = {:id => Process.pid, :seed => message_block[2]}
|
69
69
|
when :init
|
70
70
|
$init = {:seed => 'init_status', :message => 'No Init Message', :id => Process.pid} if $init.nil?
|
71
|
-
socket_send(:init_crop,:row,$init)
|
71
|
+
socket_send([:init_crop,:row,$init,@garden_path])
|
72
|
+
when :quit
|
73
|
+
pid = Process.pid
|
74
|
+
socket_send([:close,:row,{:level => :seed, :pid => pid},@garden_path])
|
75
|
+
exit
|
72
76
|
end
|
77
|
+
when :init
|
78
|
+
$init = {:seed => 'init_status', :message => 'No Init Message', :id => Process.pid} if $init.nil?
|
79
|
+
socket_send([:init_crop,:row,$init,@garden_path])
|
80
|
+
when :quit
|
81
|
+
pid = Process.pid
|
82
|
+
socket_send([:close,:row,{:level => :seed, :pid => pid},@garden_path])
|
83
|
+
exit
|
73
84
|
end
|
74
85
|
elsif ! $seed[:success].nil?
|
75
86
|
if @seed_all
|
76
|
-
socket_send(:seed_all_crop,:row,$seed)
|
87
|
+
socket_send([:seed_all_crop,:row,$seed,@garden_path])
|
77
88
|
@seed_all = false
|
78
89
|
else
|
79
|
-
socket_send(:crop,:row,$seed)
|
90
|
+
socket_send([:crop,:row,$seed,@garden_path])
|
80
91
|
end
|
81
92
|
$seed = nil;
|
82
93
|
else
|
data/lib/gardener.rb
CHANGED
@@ -48,7 +48,7 @@ class Gardener
|
|
48
48
|
# === Example
|
49
49
|
# puts gardener.init_status.inspect # => [{:message=>"init ok", :success=>true, :pid=>4760}, {:message=>"init failed", :success=>false, :pid=>4761}]
|
50
50
|
def init_status
|
51
|
-
message_block = socket_duplex(:init,:gardener,@garden_rows.pids.size)
|
51
|
+
message_block = socket_duplex([:init,:gardener,@garden_rows.pids.size,@garden_path])
|
52
52
|
message_block[2].map! do |row|
|
53
53
|
{:success => row[:success], :message => row[:message], :pid => row[:id]}
|
54
54
|
end
|
@@ -62,7 +62,7 @@ class Gardener
|
|
62
62
|
# id_seed_1 = gardener.seed("system 'ruby -v'")
|
63
63
|
|
64
64
|
def seed(data)
|
65
|
-
message_block = socket_duplex(:seed,:
|
65
|
+
message_block = socket_duplex([:seed,:one,data,@garden_path])
|
66
66
|
return message_block[2]
|
67
67
|
end
|
68
68
|
|
@@ -74,8 +74,7 @@ class Gardener
|
|
74
74
|
# result = gardener.seed_all("pref local") # => [{:success=>true, :message=>["row pref changed to local"], :seed=>"pref local", :pid=>14915},
|
75
75
|
# {:success=>true, :message=>["row pref changed to local"], :seed=>"pref local", :pid=>14913}]
|
76
76
|
def seed_all(data)
|
77
|
-
|
78
|
-
message_block = socket_duplex(:seed_all,:gardener,seed)
|
77
|
+
message_block = socket_duplex([:seed,@garden_rows.pids.size,data,@garden_path])
|
79
78
|
message_block[2].map! do |row|
|
80
79
|
{:success => row[:success], :message => row[:message], :pid => row[:id]}
|
81
80
|
end
|
@@ -94,7 +93,7 @@ class Gardener
|
|
94
93
|
# puts "progress is now #{progress}" # => progress is now 0.75
|
95
94
|
|
96
95
|
def growth(data=:progress)
|
97
|
-
message_block = socket_duplex(:growth,:gardener,data)
|
96
|
+
message_block = socket_duplex([:growth,:gardener,data,@garden_path])
|
98
97
|
return message_block[2]
|
99
98
|
end
|
100
99
|
|
@@ -113,7 +112,7 @@ class Gardener
|
|
113
112
|
# seed1_result = gardener.harvest(id_seed_1)
|
114
113
|
|
115
114
|
def harvest(data)
|
116
|
-
message_block = socket_duplex(:harvest,:gardener,data)
|
115
|
+
message_block = socket_duplex([:harvest,:gardener,data,@garden_path])
|
117
116
|
return message_block[2]
|
118
117
|
end
|
119
118
|
|
@@ -123,7 +122,7 @@ class Gardener
|
|
123
122
|
# final_harvest = gardener.close
|
124
123
|
|
125
124
|
def close
|
126
|
-
message_block = socket_duplex(:close,:gardener,{:level => :garden, :pid => @garden_rows.pids})
|
125
|
+
message_block = socket_duplex([:close,:gardener,{:level => :garden, :pid => @garden_rows.pids},@garden_path])
|
127
126
|
return message_block[2]
|
128
127
|
end
|
129
128
|
|
data/lib/toolshed.rb
CHANGED
@@ -52,8 +52,8 @@ module Toolshed
|
|
52
52
|
# * _command_ = command part of the sent packet
|
53
53
|
# * _data_ = data part of the sent packet
|
54
54
|
# * _server_socket_path_ = a UNIXServer socket path for the packets to be sent to
|
55
|
-
def socket_send(
|
56
|
-
send_block(
|
55
|
+
def socket_send(message_block)
|
56
|
+
send_block(message_block)
|
57
57
|
end
|
58
58
|
|
59
59
|
# The +socket_duplex+ method open a UNIXSocket and send packets to a UNIXServer socket, then wait for loopback communication from destination and return results like +socket_recv+.
|
@@ -61,8 +61,8 @@ module Toolshed
|
|
61
61
|
# * _command_ = command part of the sent packet
|
62
62
|
# * _data_ = data part of the sent packet
|
63
63
|
# * _server_socket_path_ = a UNIXServer socket path for the packets to be sent to
|
64
|
-
def socket_duplex(
|
65
|
-
send_block(
|
64
|
+
def socket_duplex(message_block)
|
65
|
+
send_block(message_block)
|
66
66
|
Marshal.load(recv_whole_block)
|
67
67
|
end
|
68
68
|
|
@@ -121,10 +121,10 @@ module Toolshed
|
|
121
121
|
# * _command_ = command part of the sent packet
|
122
122
|
# * _data_ = data part of the sent packet
|
123
123
|
# * _server_socket_path_ = the UNIXServer socket path to send to
|
124
|
-
def send_block(
|
124
|
+
def send_block(message_block)
|
125
125
|
begin
|
126
|
-
client = UNIXSocket.open(
|
127
|
-
client.send(Marshal.dump([
|
126
|
+
client = UNIXSocket.open(message_block[3])
|
127
|
+
client.send(Marshal.dump(message_block[0..2] + [@my_socket_path]),0)
|
128
128
|
client.close
|
129
129
|
rescue Errno::EADDRINUSE
|
130
130
|
retry
|
data/test/tc_burst.rb
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
|
2
|
+
require 'test/unit'
|
3
|
+
require 'abundance'
|
4
|
+
|
5
|
+
class TestHighAPI < Test::Unit::TestCase
|
6
|
+
|
7
|
+
def test_burst1
|
8
|
+
check_init
|
9
|
+
seed_1000x10
|
10
|
+
check_init
|
11
|
+
seed_2000
|
12
|
+
check_seed_all
|
13
|
+
seed_2000
|
14
|
+
check_crop
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
def setup
|
19
|
+
@g = Abundance.gardener(:wheelbarrow => 124, :rows => 8, :init_timeout => 2) do
|
20
|
+
Abundance.init_status(true,Process.pid)
|
21
|
+
Abundance.grow do |seed|
|
22
|
+
sprout = seed.sprout
|
23
|
+
if sprout.is_a?(Hash)
|
24
|
+
seed.crop(true, "gardener: #{sprout[:jo]} - #{sprout[:lo]}")
|
25
|
+
elsif sprout.is_a?(Array)
|
26
|
+
result = sprout[0] ** sprout[1]
|
27
|
+
seed.crop(true, "gardener: #{result.to_s}")
|
28
|
+
else
|
29
|
+
seed.crop(true, "????????????????")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def teardown
|
36
|
+
@g.close
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def seed_1000x10
|
42
|
+
(1..1000).each do |num1|
|
43
|
+
(1..10).each do |num2|
|
44
|
+
@g.seed([num1,num2])
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def seed_2000
|
50
|
+
seed = {:jo => 'ker', :lo => 'ver'}
|
51
|
+
2000.times do
|
52
|
+
@g.seed(seed)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def check_init
|
57
|
+
@g.init_status.each do |init|
|
58
|
+
assert_not_nil(init[:message])
|
59
|
+
assert_not_nil(init[:success])
|
60
|
+
assert_not_nil(init[:pid])
|
61
|
+
|
62
|
+
assert_not_equal(Process.pid,init[:message])
|
63
|
+
assert_equal(init[:message],init[:pid])
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def check_seed_all
|
68
|
+
all = @g.seed_all([1000,1000])
|
69
|
+
assert_equal(8,all.size)
|
70
|
+
all.map! { |seed| seed[:message] == "gardener: #{(1000**1000).to_s}" }
|
71
|
+
assert( all.uniq.size == 1 && all[0] == true )
|
72
|
+
end
|
73
|
+
|
74
|
+
def check_crop
|
75
|
+
crop = @g.harvest(:full_crop)
|
76
|
+
assert_equal(14000,crop.size)
|
77
|
+
assert_kind_of(Array,crop)
|
78
|
+
assert_kind_of(Hash,crop[0])
|
79
|
+
assert( ! crop[0][:success].nil? && (crop[0][:success] == true || crop[0][:success] == false))
|
80
|
+
assert(crop[0][:seed].class == Array || crop[0][:seed].class == Hash)
|
81
|
+
assert_kind_of(String,crop[0][:message])
|
82
|
+
assert_kind_of(Numeric,crop[0][:id])
|
83
|
+
end
|
84
|
+
end
|
data/test/ts_abundance.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: abundance
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Louis-Philippe Perron
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-01-
|
12
|
+
date: 2009-01-16 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -29,6 +29,7 @@ files:
|
|
29
29
|
- lib/gardener.rb
|
30
30
|
- lib/seed.rb
|
31
31
|
- lib/toolshed.rb
|
32
|
+
- test/tc_burst.rb
|
32
33
|
- test/tc_high_api.rb
|
33
34
|
- test/tc_multi_gardener.rb
|
34
35
|
- test/tc_robustness.rb
|