abundance 1.2.3 → 1.2.4
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/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
|