iotas 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/.travis.yml +7 -0
- data/Changelog +5 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +28 -0
- data/LICENSE +661 -0
- data/README.md +18 -0
- data/Rakefile +6 -0
- data/iotas.gemspec +28 -0
- data/lib/iotas/board.rb +69 -0
- data/lib/iotas/door.rb +91 -0
- data/lib/iotas/iota.rb +64 -0
- data/lib/iotas/link.rb +70 -0
- data/lib/iotas/particle.rb +213 -0
- data/lib/iotas/room.rb +192 -0
- data/lib/iotas/spin.rb +150 -0
- data/lib/iotas.rb +51 -0
- data/lib/version.rb +28 -0
- data/spec/board_spec.rb +95 -0
- data/spec/door_spec.rb +94 -0
- data/spec/link_spec.rb +38 -0
- data/spec/particle_spec.rb +240 -0
- data/spec/room_spec.rb +304 -0
- data/spec/spec_helper.rb +38 -0
- data/spec/spin_spec.rb +129 -0
- data/spec/spot_spec.rb +26 -0
- data/test/test_evendoors.rb +168 -0
- metadata +132 -0
data/lib/iotas/room.rb
ADDED
@@ -0,0 +1,192 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
# -*- coding: UTF-8 -*-
|
3
|
+
#
|
4
|
+
# Copyright 2012 Jérémy Zurcher <jeremy@asynk.ch>
|
5
|
+
#
|
6
|
+
# This file is part of iotas.
|
7
|
+
#
|
8
|
+
# iotas is free software: you can redistribute it and/or modify
|
9
|
+
# it under the terms of the GNU Affero General Public License as published by
|
10
|
+
# the Free Software Foundation, either version 3 of the License, or
|
11
|
+
# (at your option) any later version.
|
12
|
+
#
|
13
|
+
# iotas is distributed in the hope that it will be useful,
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
# GNU Affero General Public License for more details.
|
17
|
+
#
|
18
|
+
# You should have received a copy of the GNU Affero General Public License
|
19
|
+
# along with iotas. If not, see <http://www.gnu.org/licenses/>.
|
20
|
+
|
21
|
+
#
|
22
|
+
module Iotas
|
23
|
+
#
|
24
|
+
ERROR_ROUTE_NS = 'routing error: no source'.freeze
|
25
|
+
ERROR_ROUTE_RRWD = 'routing error: right room, wrong door'.freeze
|
26
|
+
ERROR_ROUTE_DDWR = 'routing error: drill down, wrong room'.freeze
|
27
|
+
ERROR_ROUTE_TRWR = 'routing error: top room, wrong room'.freeze
|
28
|
+
ERROR_ROUTE_NDNL = 'routing error: no destination, no link'.freeze
|
29
|
+
ERROR_ROUTE_SND = 'routing error: system no destination'.freeze
|
30
|
+
#
|
31
|
+
class Room < Iota
|
32
|
+
#
|
33
|
+
def initialize n, p
|
34
|
+
super n, p
|
35
|
+
@iotas = {}
|
36
|
+
@links = {}
|
37
|
+
end
|
38
|
+
#
|
39
|
+
def to_json *a
|
40
|
+
{
|
41
|
+
'kls' => self.class.name,
|
42
|
+
'name' => @name,
|
43
|
+
'iotas' => @iotas,
|
44
|
+
'links' => @links
|
45
|
+
}.to_json *a
|
46
|
+
end
|
47
|
+
#
|
48
|
+
def self.json_create o
|
49
|
+
raise Iotas::Exception.new "JSON #{o['kls']} != #{self.name}" if o['kls'] != self.name
|
50
|
+
room = self.new o['name'], o['parent']
|
51
|
+
o['iotas'].each do |name,iota|
|
52
|
+
eval( iota['kls'] ).json_create(iota.merge!('parent'=>room))
|
53
|
+
end
|
54
|
+
o['links'].each do |src,links|
|
55
|
+
links.each do |link|
|
56
|
+
room.add_link Iotas::Link.json_create(link)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
room
|
60
|
+
end
|
61
|
+
#
|
62
|
+
def add_iota s
|
63
|
+
raise Iotas::Exception.new "Iota #{s.name} already has #{s.parent.name} as parent" if not s.parent.nil? and s.parent!=self
|
64
|
+
raise Iotas::Exception.new "Iota #{s.name} already exists in #{path}" if @iotas.has_key? s.name
|
65
|
+
s.parent = self if s.parent.nil?
|
66
|
+
@iotas[s.name]=s
|
67
|
+
end
|
68
|
+
#
|
69
|
+
def add_link l
|
70
|
+
l.door = @iotas[l.src]
|
71
|
+
raise Iotas::Exception.new "Link source #{l.src} does not exist in #{path}" if l.door.nil?
|
72
|
+
(@links[l.src] ||= [])<< l
|
73
|
+
end
|
74
|
+
#
|
75
|
+
def start!
|
76
|
+
puts " * start #{path}" if @spin.debug_routing
|
77
|
+
@iotas.values.each do |iota| iota.start! end
|
78
|
+
end
|
79
|
+
#
|
80
|
+
def stop!
|
81
|
+
puts " * stop #{path}" if @spin.debug_routing
|
82
|
+
@iotas.values.each do |iota| iota.stop! end
|
83
|
+
end
|
84
|
+
#
|
85
|
+
def search_down spath
|
86
|
+
return self if spath==path
|
87
|
+
return nil if (spath=~/^#{path}\/(\w+)\/?/)!=0
|
88
|
+
if iota = @iotas[$1]
|
89
|
+
return iota if iota.path==spath # needed as Door doesn't implement #search_down
|
90
|
+
return iota.search_down spath
|
91
|
+
end
|
92
|
+
nil
|
93
|
+
end
|
94
|
+
#
|
95
|
+
def try_links p
|
96
|
+
puts " -> try_links ..." if @spin.debug_routing
|
97
|
+
links = @links[p.src.name]
|
98
|
+
return false if links.nil?
|
99
|
+
pending_link = nil
|
100
|
+
apply_link = false
|
101
|
+
links.each do |link|
|
102
|
+
apply_link = link.cond_fields.nil? # unconditional link
|
103
|
+
p.set_link_fields link.cond_fields if not apply_link
|
104
|
+
if apply_link or (p.link_value==link.cond_value)
|
105
|
+
# link matches !
|
106
|
+
if pending_link
|
107
|
+
p2 = @spin.require_p p.class
|
108
|
+
p2.clone_data p
|
109
|
+
p2.apply_link! link
|
110
|
+
send_p p2
|
111
|
+
end
|
112
|
+
pending_link = link
|
113
|
+
end
|
114
|
+
end
|
115
|
+
if pending_link
|
116
|
+
p.apply_link! pending_link
|
117
|
+
send_p p
|
118
|
+
end
|
119
|
+
(not pending_link.nil?)
|
120
|
+
end
|
121
|
+
#
|
122
|
+
def route_p p
|
123
|
+
if p.room.nil? or p.room==path
|
124
|
+
if door = @iotas[p.door]
|
125
|
+
p.dst_routed! door
|
126
|
+
else
|
127
|
+
p.error! Iotas::ERROR_ROUTE_RRWD
|
128
|
+
end
|
129
|
+
elsif (p.room=~/^#{path}\/(.*)/)==0
|
130
|
+
room, *more = $1.split Iotas::PATH_SEP
|
131
|
+
if child=@iotas[room]
|
132
|
+
child.route_p p
|
133
|
+
else
|
134
|
+
p.error! Iotas::ERROR_ROUTE_DDWR
|
135
|
+
end
|
136
|
+
elsif @parent
|
137
|
+
@parent.route_p p
|
138
|
+
else
|
139
|
+
p.error! Iotas::ERROR_ROUTE_TRWR
|
140
|
+
end
|
141
|
+
end
|
142
|
+
#
|
143
|
+
def send_p p
|
144
|
+
puts " * send_p #{(p.next_dst.nil? ? 'no dst' : p.next_dst)} ..." if @spin.debug_routing
|
145
|
+
if p.src.nil?
|
146
|
+
# do not route orphan particles !!
|
147
|
+
p.error! Iotas::ERROR_ROUTE_NS, @spin
|
148
|
+
elsif p.next_dst
|
149
|
+
p.split_dst!
|
150
|
+
if p.door
|
151
|
+
route_p p
|
152
|
+
else
|
153
|
+
# boomerang
|
154
|
+
p.dst_routed! p.src
|
155
|
+
end
|
156
|
+
elsif try_links p
|
157
|
+
return
|
158
|
+
else
|
159
|
+
p.error! Iotas::ERROR_ROUTE_NDNL
|
160
|
+
end
|
161
|
+
puts " -> #{p.dst.path}#{Iotas::ACT_SEP}#{p.action}" if @spin.debug_routing
|
162
|
+
@spin.post_p p
|
163
|
+
end
|
164
|
+
#
|
165
|
+
def send_sys_p p
|
166
|
+
puts " * send_sys_p #{(p.next_dst.nil? ? 'no dst' : p.next_dst)} ..." if @spin.debug_routing
|
167
|
+
if p.next_dst
|
168
|
+
p.split_dst!
|
169
|
+
if p.door
|
170
|
+
route_p p
|
171
|
+
elsif p.action
|
172
|
+
p.dst_routed! @spin
|
173
|
+
end
|
174
|
+
else
|
175
|
+
p.error! Iotas::ERROR_ROUTE_SND
|
176
|
+
end
|
177
|
+
puts " -> #{p.dst.path}#{Iotas::ACT_SEP}#{p.action}" if @spin.debug_routing
|
178
|
+
@spin.post_sys_p p
|
179
|
+
end
|
180
|
+
#
|
181
|
+
def process_sys_p p
|
182
|
+
if p.action==Iotas::SYS_ACT_ADD_LINK
|
183
|
+
add_link Iotas::Link.from_particle_data p
|
184
|
+
end
|
185
|
+
@spin.release_p p
|
186
|
+
end
|
187
|
+
#
|
188
|
+
end
|
189
|
+
#
|
190
|
+
end
|
191
|
+
#
|
192
|
+
# EOF
|
data/lib/iotas/spin.rb
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
# -*- coding: UTF-8 -*-
|
3
|
+
#
|
4
|
+
# Copyright 2012 Jérémy Zurcher <jeremy@asynk.ch>
|
5
|
+
#
|
6
|
+
# This file is part of iotas.
|
7
|
+
#
|
8
|
+
# iotas is free software: you can redistribute it and/or modify
|
9
|
+
# it under the terms of the GNU Affero General Public License as published by
|
10
|
+
# the Free Software Foundation, either version 3 of the License, or
|
11
|
+
# (at your option) any later version.
|
12
|
+
#
|
13
|
+
# iotas is distributed in the hope that it will be useful,
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
# GNU Affero General Public License for more details.
|
17
|
+
#
|
18
|
+
# You should have received a copy of the GNU Affero General Public License
|
19
|
+
# along with iotas. If not, see <http://www.gnu.org/licenses/>.
|
20
|
+
|
21
|
+
#
|
22
|
+
module Iotas
|
23
|
+
#
|
24
|
+
class Spin < Room
|
25
|
+
#
|
26
|
+
def initialize n, o={}
|
27
|
+
super n, nil
|
28
|
+
#
|
29
|
+
@pool = {} # per particle class free list
|
30
|
+
@sys_fifo = [] # system particles fifo list
|
31
|
+
@app_fifo = [] # application particles fifo list
|
32
|
+
#
|
33
|
+
@run = false
|
34
|
+
@hibernation = o['hibernation']||false
|
35
|
+
@hibernate_path = 'iotas-hibernate-'+n+'.json'
|
36
|
+
@debug_errors = o[:debug_errors]||o['debug_errors']||false
|
37
|
+
@debug_routing = o[:debug_routing]||o['debug_routing']||false
|
38
|
+
#
|
39
|
+
if not o.empty?
|
40
|
+
o['iotas'].each do |name,iota|
|
41
|
+
Iotas::Room.json_create(iota.merge!('parent'=>self))
|
42
|
+
end if o['iotas']
|
43
|
+
o['app_fifo'].each do |particle|
|
44
|
+
@app_fifo << Iotas::Particle.json_create(particle.merge!('spin'=>self))
|
45
|
+
end if o['app_fifo']
|
46
|
+
o['sys_fifo'].each do |particle|
|
47
|
+
@sys_fifo << Iotas::Particle.json_create(particle.merge!('spin'=>self))
|
48
|
+
end if o['sys_fifo']
|
49
|
+
end
|
50
|
+
end
|
51
|
+
#
|
52
|
+
attr_accessor :run, :hibernate_path, :debug_errors, :debug_routing
|
53
|
+
#
|
54
|
+
def to_json *a
|
55
|
+
{
|
56
|
+
'kls' => self.class.name,
|
57
|
+
'timestamp' => Time.now,
|
58
|
+
'name' => @name,
|
59
|
+
'hibernation' => @hibernation,
|
60
|
+
'iotas' => @iotas,
|
61
|
+
'sys_fifo' => @sys_fifo,
|
62
|
+
'app_fifo' => @app_fifo,
|
63
|
+
'debug_errors' => @debug_errors,
|
64
|
+
'debug_routing' => @debug_routing
|
65
|
+
}.to_json(*a)
|
66
|
+
end
|
67
|
+
#
|
68
|
+
def self.json_create o
|
69
|
+
raise Iotas::Exception.new "JSON #{o['kls']} != #{self.name}" if o['kls'] != self.name
|
70
|
+
self.new o['name'], o
|
71
|
+
end
|
72
|
+
#
|
73
|
+
def clear!
|
74
|
+
@iotas.clear
|
75
|
+
@pool.clear
|
76
|
+
@sys_fifo.clear
|
77
|
+
@app_fifo.clear
|
78
|
+
end
|
79
|
+
#
|
80
|
+
#
|
81
|
+
def release_p p
|
82
|
+
# hope there is no circular loop
|
83
|
+
while p2=p.merged_shift
|
84
|
+
release_p p2
|
85
|
+
end
|
86
|
+
( @pool[p.class] ||= [] ) << p
|
87
|
+
end
|
88
|
+
#
|
89
|
+
def require_p p_kls
|
90
|
+
l = @pool[p_kls]
|
91
|
+
return p_kls.new if l.nil?
|
92
|
+
p = l.pop
|
93
|
+
return p_kls.new if p.nil?
|
94
|
+
p.reset!
|
95
|
+
p
|
96
|
+
end
|
97
|
+
#
|
98
|
+
def post_p p
|
99
|
+
@app_fifo << p
|
100
|
+
end
|
101
|
+
#
|
102
|
+
def post_sys_p p
|
103
|
+
@sys_fifo << p
|
104
|
+
end
|
105
|
+
#
|
106
|
+
def process_sys_p p
|
107
|
+
if p.action==Iotas::SYS_ACT_HIBERNATE
|
108
|
+
stop!
|
109
|
+
hibernate! p[FIELD_HIBERNATE_PATH]
|
110
|
+
else
|
111
|
+
super p
|
112
|
+
end
|
113
|
+
end
|
114
|
+
#
|
115
|
+
def spin!
|
116
|
+
@iotas.values.each do |iota| iota.start! end unless @hibernation
|
117
|
+
@run = true
|
118
|
+
@hibernation = false
|
119
|
+
while @run and (@sys_fifo.length>0 or @app_fifo.length>0)
|
120
|
+
while @run and @sys_fifo.length>0
|
121
|
+
p = @sys_fifo.shift
|
122
|
+
p.dst.process_sys_p p
|
123
|
+
end
|
124
|
+
while @run and @app_fifo.length>0
|
125
|
+
p = @app_fifo.shift
|
126
|
+
p.dst.process_p p
|
127
|
+
break
|
128
|
+
end
|
129
|
+
end
|
130
|
+
@iotas.values.each do |iota| iota.stop! end unless @hibernation
|
131
|
+
end
|
132
|
+
#
|
133
|
+
def stop!
|
134
|
+
@run=false
|
135
|
+
end
|
136
|
+
#
|
137
|
+
def hibernate! path=nil
|
138
|
+
@hibernation = true
|
139
|
+
File.open(path||@hibernate_path,'w') do |f| f << JSON.pretty_generate(self) end
|
140
|
+
end
|
141
|
+
#
|
142
|
+
def self.resume! path
|
143
|
+
self.json_create JSON.load File.open(path,'r') { |f| f.read }
|
144
|
+
end
|
145
|
+
#
|
146
|
+
end
|
147
|
+
#
|
148
|
+
end
|
149
|
+
#
|
150
|
+
# EOF
|
data/lib/iotas.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
# -*- coding: UTF-8 -*-
|
3
|
+
#
|
4
|
+
# Copyright 2012 Jérémy Zurcher <jeremy@asynk.ch>
|
5
|
+
#
|
6
|
+
# This file is part of iotas.
|
7
|
+
#
|
8
|
+
# iotas is free software: you can redistribute it and/or modify
|
9
|
+
# it under the terms of the GNU Affero General Public License as published by
|
10
|
+
# the Free Software Foundation, either version 3 of the License, or
|
11
|
+
# (at your option) any later version.
|
12
|
+
#
|
13
|
+
# iotas is distributed in the hope that it will be useful,
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
# GNU Affero General Public License for more details.
|
17
|
+
#
|
18
|
+
# You should have received a copy of the GNU Affero General Public License
|
19
|
+
# along with iotas. If not, see <http://www.gnu.org/licenses/>.
|
20
|
+
|
21
|
+
require 'version'
|
22
|
+
#
|
23
|
+
module Iotas
|
24
|
+
#
|
25
|
+
PATH_SEP = '/'.freeze
|
26
|
+
LINK_SEP = ','.freeze
|
27
|
+
ACT_SEP = '?'.freeze
|
28
|
+
#
|
29
|
+
ACT_GET = 'get'.freeze
|
30
|
+
ACT_ERROR = 'error'.freeze
|
31
|
+
#
|
32
|
+
SYS_ACT_HIBERNATE = 'hibernate'.freeze
|
33
|
+
SYS_ACT_ADD_LINK = 'sys_add_link'.freeze
|
34
|
+
#
|
35
|
+
FIELD_ERROR_MSG = 'edoors_error'.freeze
|
36
|
+
FIELD_HIBERNATE_PATH= 'hibernate_path'.freeze
|
37
|
+
#
|
38
|
+
class Exception < ::Exception; end
|
39
|
+
#
|
40
|
+
end
|
41
|
+
#
|
42
|
+
require 'json'
|
43
|
+
require 'iotas/particle'
|
44
|
+
require 'iotas/iota'
|
45
|
+
require 'iotas/room'
|
46
|
+
require 'iotas/spin'
|
47
|
+
require 'iotas/door'
|
48
|
+
require 'iotas/board'
|
49
|
+
require 'iotas/link'
|
50
|
+
#
|
51
|
+
# EOF
|
data/lib/version.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
# -*- coding: UTF-8 -*-
|
3
|
+
#
|
4
|
+
# Copyright 2012 Jérémy Zurcher <jeremy@asynk.ch>
|
5
|
+
#
|
6
|
+
# This file is part of iotas.
|
7
|
+
#
|
8
|
+
# iotas is free software: you can redistribute it and/or modify
|
9
|
+
# it under the terms of the GNU Affero General Public License as published by
|
10
|
+
# the Free Software Foundation, either version 3 of the License, or
|
11
|
+
# (at your option) any later version.
|
12
|
+
#
|
13
|
+
# iotas is distributed in the hope that it will be useful,
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
# GNU Affero General Public License for more details.
|
17
|
+
#
|
18
|
+
# You should have received a copy of the GNU Affero General Public License
|
19
|
+
# along with iotas. If not, see <http://www.gnu.org/licenses/>.
|
20
|
+
|
21
|
+
#
|
22
|
+
module Iotas
|
23
|
+
#
|
24
|
+
VERSION = "0.0.2"
|
25
|
+
#
|
26
|
+
end
|
27
|
+
#
|
28
|
+
# EOF
|
data/spec/board_spec.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
# -*- coding: UTF-8 -*-
|
3
|
+
#
|
4
|
+
|
5
|
+
require 'spec_helper'
|
6
|
+
#
|
7
|
+
describe Iotas::Board do
|
8
|
+
#
|
9
|
+
before (:all) do
|
10
|
+
@spin = Iotas::Spin.new 'dom0'
|
11
|
+
end
|
12
|
+
#
|
13
|
+
before(:each) do
|
14
|
+
@spin.clear!
|
15
|
+
end
|
16
|
+
#
|
17
|
+
it "require_p release_p" do
|
18
|
+
board = Iotas::Board.new 'hell', @spin
|
19
|
+
p0 = board.require_p Iotas::Particle
|
20
|
+
p0.src.should be board
|
21
|
+
p1 = board.require_p Iotas::Particle
|
22
|
+
p1.src.should be board
|
23
|
+
(p0===p1).should be_false
|
24
|
+
board.release_p p0
|
25
|
+
p2 = board.require_p Iotas::Particle
|
26
|
+
p2.src.should be board
|
27
|
+
(p0===p2).should be_true
|
28
|
+
end
|
29
|
+
#
|
30
|
+
it "particle wait and merge" do
|
31
|
+
p0 = Iotas::Particle.new
|
32
|
+
p0['k0'] = 'v0'
|
33
|
+
p0['k1'] = 'neither'
|
34
|
+
p0['k2'] = 'v2'
|
35
|
+
p0.set_link_fields 'k0,k2'
|
36
|
+
p0.link_value.should eql 'v0v2'
|
37
|
+
p1 = Iotas::Particle.new
|
38
|
+
p1['k0'] = 'v0'
|
39
|
+
p1['k1'] = 'nore'
|
40
|
+
p1['k2'] = 'v2'
|
41
|
+
p1.set_link_fields 'k0,k2'
|
42
|
+
p1.link_value.should eql 'v0v2'
|
43
|
+
P0 = p0
|
44
|
+
P1 = p1
|
45
|
+
class Board0 < Iotas::Board
|
46
|
+
attr_reader :ok, :follow
|
47
|
+
def receive_p p
|
48
|
+
@ok = false
|
49
|
+
case p.action
|
50
|
+
when Iotas::ACT_FOLLOW
|
51
|
+
@follow = true
|
52
|
+
@ok = (p===P0 and p.merged(0)===P1)
|
53
|
+
else
|
54
|
+
@follow = false
|
55
|
+
@ok = (p===P1 and p.merged(0)===P0)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
b0 = Board0.new 'door0', @spin
|
60
|
+
b0.process_p p0
|
61
|
+
p0.merged(0).should be_nil
|
62
|
+
b0.process_p p1
|
63
|
+
b0.ok.should be_true
|
64
|
+
b0.follow.should be_false
|
65
|
+
#
|
66
|
+
p1.merged_shift
|
67
|
+
#
|
68
|
+
b0.process_p p0
|
69
|
+
p0.merged(0).should be_nil
|
70
|
+
# need to set it to p0 too, so case in Board0 is ok
|
71
|
+
p0.set_dst! Iotas::ACT_FOLLOW
|
72
|
+
p0.split_dst!
|
73
|
+
p1.set_dst! Iotas::ACT_FOLLOW
|
74
|
+
p1.split_dst!
|
75
|
+
b0.process_p p1
|
76
|
+
b0.ok.should be_true
|
77
|
+
b0.follow.should be_true
|
78
|
+
end
|
79
|
+
#
|
80
|
+
it "board->json->board" do
|
81
|
+
board = Iotas::Board.new 'hell', @spin
|
82
|
+
p0 = Iotas::Particle.new
|
83
|
+
p1 = Iotas::Particle.new
|
84
|
+
p1['v0']=0
|
85
|
+
p1.set_link_fields 'v0'
|
86
|
+
board.process_p p0
|
87
|
+
board.process_p p1
|
88
|
+
hell = Iotas::Board.json_create( JSON.load( JSON.generate(board) ) )
|
89
|
+
board.name.should eql hell.name
|
90
|
+
JSON.generate(board).should eql JSON.generate(hell)
|
91
|
+
end
|
92
|
+
#
|
93
|
+
end
|
94
|
+
#
|
95
|
+
# EOF
|
data/spec/door_spec.rb
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
# -*- coding: UTF-8 -*-
|
3
|
+
#
|
4
|
+
|
5
|
+
require 'spec_helper'
|
6
|
+
#
|
7
|
+
describe Iotas::Door do
|
8
|
+
#
|
9
|
+
before (:all) do
|
10
|
+
@spin = Iotas::Spin.new 'dom0'
|
11
|
+
end
|
12
|
+
#
|
13
|
+
before(:each) do
|
14
|
+
@spin.clear!
|
15
|
+
end
|
16
|
+
#
|
17
|
+
it "require_p release_p" do
|
18
|
+
door = Iotas::Door.new 'hell', @spin
|
19
|
+
p0 = door.require_p Iotas::Particle
|
20
|
+
p0.src.should be door
|
21
|
+
p1 = door.require_p Iotas::Particle
|
22
|
+
p1.src.should be door
|
23
|
+
(p0===p1).should be_false
|
24
|
+
door.release_p p0
|
25
|
+
p2 = door.require_p Iotas::Particle
|
26
|
+
p2.src.should be door
|
27
|
+
(p0===p2).should be_true
|
28
|
+
end
|
29
|
+
#
|
30
|
+
it "NoMethodError when receive_p not overridden" do
|
31
|
+
class Door0 < Iotas::Door
|
32
|
+
end
|
33
|
+
f = Fake.new 'fake', @spin
|
34
|
+
d0 = Door0.new 'door0', f
|
35
|
+
p0 = d0.require_p Iotas::Particle
|
36
|
+
lambda { d0.process_p p0 }.should raise_error(NoMethodError)
|
37
|
+
end
|
38
|
+
#
|
39
|
+
it "send_p, send_sys_p, release_p and release of lost particles" do
|
40
|
+
class Door0 < Iotas::Door
|
41
|
+
def receive_p p
|
42
|
+
case p.action
|
43
|
+
when 'RELEASE'
|
44
|
+
release_p p
|
45
|
+
when 'SEND'
|
46
|
+
send_p p
|
47
|
+
when 'SEND_SYS'
|
48
|
+
send_sys_p p
|
49
|
+
else
|
50
|
+
# lost!!
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
f = Fake.new 'fake', @spin
|
55
|
+
d0 = Door0.new 'door0', f
|
56
|
+
p0 = d0.require_p Iotas::Particle
|
57
|
+
#
|
58
|
+
p0.set_dst! 'SEND'
|
59
|
+
p0.split_dst!
|
60
|
+
d0.process_p p0
|
61
|
+
f.p.should eql p0
|
62
|
+
#
|
63
|
+
p0.set_dst! 'SEND_SYS'
|
64
|
+
p0.split_dst!
|
65
|
+
d0.process_p p0
|
66
|
+
f.sp.should eql p0
|
67
|
+
#
|
68
|
+
p0.set_dst! 'RELEASE'
|
69
|
+
p0.split_dst!
|
70
|
+
d0.process_p p0
|
71
|
+
p1 = d0.require_p Iotas::Particle
|
72
|
+
p1.should be p0
|
73
|
+
#
|
74
|
+
p0.set_dst! 'LOST'
|
75
|
+
p0.split_dst!
|
76
|
+
d0.process_p p0
|
77
|
+
p1 = d0.require_p Iotas::Particle
|
78
|
+
p1.should be p0
|
79
|
+
#
|
80
|
+
d0.process_sys_p p0
|
81
|
+
p1 = @spin.require_p Iotas::Particle
|
82
|
+
p1.should be p0
|
83
|
+
end
|
84
|
+
#
|
85
|
+
it "door->json->door" do
|
86
|
+
door = Iotas::Door.new 'hell', @spin
|
87
|
+
hell = Iotas::Door.json_create( JSON.load( JSON.generate(door) ) )
|
88
|
+
door.name.should eql hell.name
|
89
|
+
JSON.generate(door).should eql JSON.generate(hell)
|
90
|
+
end
|
91
|
+
#
|
92
|
+
end
|
93
|
+
#
|
94
|
+
# EOF
|
data/spec/link_spec.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
# -*- coding: UTF-8 -*-
|
3
|
+
#
|
4
|
+
|
5
|
+
require 'spec_helper'
|
6
|
+
#
|
7
|
+
describe Iotas::Link do
|
8
|
+
#
|
9
|
+
it "from particle data" do
|
10
|
+
@spin = Iotas::Spin.new 'dom0'
|
11
|
+
p = @spin.require_p Iotas::Particle
|
12
|
+
p.set_data Iotas::LNK_SRC, 'input1'
|
13
|
+
p.set_data Iotas::LNK_DSTS, 'concat1?follow,output1'
|
14
|
+
p.set_data Iotas::LNK_FIELDS, 'f0,f2'
|
15
|
+
p.set_data Iotas::LNK_CONDF, 'f0,f1,f2'
|
16
|
+
p.set_data Iotas::LNK_CONDV, 'v0v1v2'
|
17
|
+
lnk = Iotas::Link.from_particle_data p
|
18
|
+
lnk.src.should eql 'input1'
|
19
|
+
lnk.dsts.should eql 'concat1?follow,output1'
|
20
|
+
lnk.fields.should eql 'f0,f2'
|
21
|
+
lnk.cond_fields.should eql 'f0,f1,f2'
|
22
|
+
lnk.cond_value.should eql 'v0v1v2'
|
23
|
+
end
|
24
|
+
#
|
25
|
+
it "link->json->link" do
|
26
|
+
link = Iotas::Link.new 'input1', 'concat1?follow,output1', 'f0,f2', 'f0,f1,f2', 'v0v1v2'
|
27
|
+
lnk = Iotas::Link.json_create( JSON.load( JSON.generate(link) ) )
|
28
|
+
link.src.should eql lnk.src
|
29
|
+
link.dsts.should eql lnk.dsts
|
30
|
+
link.fields.should eql lnk.fields
|
31
|
+
link.cond_fields.should eql lnk.cond_fields
|
32
|
+
link.cond_value.should eql lnk.cond_value
|
33
|
+
JSON.generate(link).should eql JSON.generate(lnk)
|
34
|
+
end
|
35
|
+
#
|
36
|
+
end
|
37
|
+
#
|
38
|
+
# EOF
|