fsevent 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.
- checksums.yaml +7 -0
- data/.gitignore +34 -0
- data/LICENSE +674 -0
- data/README.md +13 -0
- data/fsevent.gemspec +43 -0
- data/lib/fsevent.rb +32 -0
- data/lib/fsevent/abstractdevice.rb +71 -0
- data/lib/fsevent/failsafedevice.rb +85 -0
- data/lib/fsevent/framework.rb +298 -0
- data/lib/fsevent/periodicschedule.rb +34 -0
- data/lib/fsevent/processdevice.rb +93 -0
- data/lib/fsevent/processdevicec.rb +79 -0
- data/lib/fsevent/schedulemerger.rb +48 -0
- data/lib/fsevent/simpledevice.rb +46 -0
- data/lib/fsevent/util.rb +77 -0
- data/sample/repeat.rb +24 -0
- data/sample/repeat2.rb +23 -0
- data/test/test_failsafedevice.rb +159 -0
- data/test/test_framework.rb +167 -0
- data/test/test_processdevice.rb +76 -0
- data/test/test_util.rb +53 -0
- data/test/test_watch.rb +169 -0
- metadata +70 -0
@@ -0,0 +1,34 @@
|
|
1
|
+
# periodicschedule.rb --- periodic schedule
|
2
|
+
#
|
3
|
+
# Copyright (C) 2014 National Institute of Advanced Industrial Science and Technology (AIST)
|
4
|
+
#
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
18
|
+
class FSEvent::PeriodicSchedule
|
19
|
+
def initialize(initial_time, interval)
|
20
|
+
@initial_time = initial_time
|
21
|
+
@interval = interval
|
22
|
+
@n = 0
|
23
|
+
end
|
24
|
+
|
25
|
+
def first
|
26
|
+
@initial_time + @n * @interval
|
27
|
+
end
|
28
|
+
|
29
|
+
def shift
|
30
|
+
t = first
|
31
|
+
@n += 1
|
32
|
+
t
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# processdevice.rb --- run device on another process
|
2
|
+
#
|
3
|
+
# Copyright (C) 2014 National Institute of Advanced Industrial Science and Technology (AIST)
|
4
|
+
#
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
18
|
+
class FSEvent::ProcessDevice < FSEvent::AbstractDevice
|
19
|
+
def self.spawner(defs)
|
20
|
+
Spawner.new(defs)
|
21
|
+
end
|
22
|
+
|
23
|
+
class Spawner
|
24
|
+
def initialize(defs)
|
25
|
+
@defs = defs
|
26
|
+
end
|
27
|
+
|
28
|
+
def assemble_code(device_name, *args)
|
29
|
+
code = ''
|
30
|
+
|
31
|
+
libpath = File.dirname(File.dirname(__FILE__))
|
32
|
+
code << "$:.unshift #{libpath.dump}\n"
|
33
|
+
|
34
|
+
code << <<-'End'
|
35
|
+
require 'fsevent'
|
36
|
+
def ep(arg) STDERR.puts arg.inspect end
|
37
|
+
End
|
38
|
+
|
39
|
+
code << "class FSEvent::ProcessDevice_#{device_name} < FSEvent::ProcessDeviceC\n#{@defs}\nend\n"
|
40
|
+
marshaled_args = Marshal.dump(args)
|
41
|
+
code << "FSEvent::ProcessDeviceC.main(FSEvent::ProcessDevice_#{device_name}.new(#{device_name.dump}, *(Marshal.load(#{marshaled_args.dump}))))\n"
|
42
|
+
end
|
43
|
+
|
44
|
+
def new(device_name, *args)
|
45
|
+
code = assemble_code(device_name, *args)
|
46
|
+
io = IO.popen([RbConfig.ruby], "r+")
|
47
|
+
io.sync = true
|
48
|
+
io.write code
|
49
|
+
io.write "__END__\n"
|
50
|
+
FSEvent::ProcessDevice.send(:new, device_name, io)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class << self
|
55
|
+
private :new
|
56
|
+
end
|
57
|
+
|
58
|
+
def initialize(device_name, io)
|
59
|
+
super device_name
|
60
|
+
@io = io
|
61
|
+
end
|
62
|
+
|
63
|
+
def call_subprocess(method, *args)
|
64
|
+
Marshal.dump([:call_child, method, *args], @io)
|
65
|
+
msgtype, *rest = Marshal.load(@io)
|
66
|
+
while msgtype == :call_parent
|
67
|
+
method, *args = rest
|
68
|
+
ret = @framework.send(method, *args)
|
69
|
+
Marshal.dump([:return_to_child, ret], @io)
|
70
|
+
msgtype, *rest = Marshal.load(@io)
|
71
|
+
end
|
72
|
+
if msgtype != :return_to_parent
|
73
|
+
raise RuntimeError, "unexpected message type: #{msgtype.inspect}"
|
74
|
+
end
|
75
|
+
rest[0]
|
76
|
+
end
|
77
|
+
#private :call_subprocess
|
78
|
+
|
79
|
+
def finish
|
80
|
+
@io.close_write
|
81
|
+
@io.close
|
82
|
+
nil
|
83
|
+
end
|
84
|
+
|
85
|
+
def framework=(framework)
|
86
|
+
@framework = framework
|
87
|
+
call_subprocess(:processdevice_framework_set)
|
88
|
+
end
|
89
|
+
|
90
|
+
def registered
|
91
|
+
call_subprocess(:processdevice_registered)
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# processdevicec.rb --- child process code for processdevice.rb
|
2
|
+
#
|
3
|
+
# Copyright (C) 2014 National Institute of Advanced Industrial Science and Technology (AIST)
|
4
|
+
#
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
18
|
+
class FSEvent::ProcessDeviceC < FSEvent::AbstractDevice
|
19
|
+
class StubFramework
|
20
|
+
def initialize(obj)
|
21
|
+
@obj = obj
|
22
|
+
end
|
23
|
+
|
24
|
+
def add_watch(watchee_device_name, status_name)
|
25
|
+
@obj.call_parent(:add_watch, watchee_device_name, status_name)
|
26
|
+
end
|
27
|
+
|
28
|
+
def status_changed(status_name, value)
|
29
|
+
@obj.call_parent(:status_changed, status_name, value)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def initialize(device_name)
|
34
|
+
super(device_name)
|
35
|
+
end
|
36
|
+
|
37
|
+
def processdevice_framework_set
|
38
|
+
framework = StubFramework.new(self)
|
39
|
+
self.framework = framework
|
40
|
+
nil
|
41
|
+
end
|
42
|
+
|
43
|
+
def processdevice_registered
|
44
|
+
registered
|
45
|
+
nil
|
46
|
+
end
|
47
|
+
|
48
|
+
def call_parent(method, *args)
|
49
|
+
Marshal.dump([:call_parent, method, *args], STDOUT)
|
50
|
+
msgtype, *rest = Marshal.load(STDIN)
|
51
|
+
while msgtype == :call_child
|
52
|
+
method, *args = rest
|
53
|
+
ret = self.send(method, *args)
|
54
|
+
Marshal.dump([:return_to_parent, ret], STDOUT)
|
55
|
+
msgtype, *rest = Marshal.load(STDIN)
|
56
|
+
end
|
57
|
+
if msgtype != :return_to_child
|
58
|
+
raise RuntimeError, "unexpected message type: #{msgtype.inspect}"
|
59
|
+
end
|
60
|
+
rest[0]
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.main(this_device)
|
64
|
+
STDOUT.sync = true
|
65
|
+
while true
|
66
|
+
begin
|
67
|
+
msgtype, *rest = Marshal.load(STDIN)
|
68
|
+
rescue EOFError
|
69
|
+
exit true
|
70
|
+
end
|
71
|
+
if msgtype != :call_child
|
72
|
+
raise RuntimeError, "unexpected message type: #{msgtype.inspect}"
|
73
|
+
end
|
74
|
+
method, *args = rest
|
75
|
+
ret = this_device.send(method, *args)
|
76
|
+
Marshal.dump([:return_to_parent, ret], STDOUT)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# schedulemerger.rb --- merge multiple schedules
|
2
|
+
#
|
3
|
+
# Copyright (C) 2014 National Institute of Advanced Industrial Science and Technology (AIST)
|
4
|
+
#
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
18
|
+
class FSEvent::ScheduleMerger
|
19
|
+
def initialize(*schedules)
|
20
|
+
@q = Depq.new
|
21
|
+
schedules.each {|s|
|
22
|
+
merge_schedule(s)
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
def merge_schedule(s)
|
27
|
+
t = s.shift
|
28
|
+
if t
|
29
|
+
@q.insert s, t
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def first
|
34
|
+
return nil if @q.empty?
|
35
|
+
@q.find_min_priority[1]
|
36
|
+
end
|
37
|
+
|
38
|
+
def shift
|
39
|
+
return nil if @q.empty?
|
40
|
+
s, t = @q.delete_min_priority
|
41
|
+
t2 = s.shift
|
42
|
+
if t2
|
43
|
+
@q.insert s, t2
|
44
|
+
end
|
45
|
+
t
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# simpledevice.rb --- simple device definition using constructor arguments
|
2
|
+
#
|
3
|
+
# Copyright (C) 2014 National Institute of Advanced Industrial Science and Technology (AIST)
|
4
|
+
#
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
18
|
+
class FSEvent::SimpleDevice < FSEvent::AbstractDevice
|
19
|
+
def initialize(device_name, initial_status, watches, registered_elapsed_time, schedule=nil, &run_block)
|
20
|
+
super device_name
|
21
|
+
@name = device_name
|
22
|
+
@initial_status = initial_status
|
23
|
+
@watches = watches
|
24
|
+
@registered_elapsed_time = registered_elapsed_time
|
25
|
+
@schedule.merge_schedule schedule if schedule
|
26
|
+
@run_block = run_block
|
27
|
+
end
|
28
|
+
attr_writer :registered_elapsed_time
|
29
|
+
|
30
|
+
def registered
|
31
|
+
@initial_status.each {|status_name, value|
|
32
|
+
define_status status_name, value
|
33
|
+
}
|
34
|
+
@watches.each {|watchee_device_name, status_name, reaction|
|
35
|
+
reaction ||= :immediate
|
36
|
+
add_watch watchee_device_name, status_name, reaction
|
37
|
+
}
|
38
|
+
if @registered_elapsed_time
|
39
|
+
set_elapsed_time @registered_elapsed_time
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def run(watched_status_change)
|
44
|
+
@run_block.call watched_status_change
|
45
|
+
end
|
46
|
+
end
|
data/lib/fsevent/util.rb
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
# util.rb --- various utilities
|
2
|
+
#
|
3
|
+
# Copyright (C) 2014 National Institute of Advanced Industrial Science and Technology (AIST)
|
4
|
+
#
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
18
|
+
module FSEvent::Util
|
19
|
+
module_function
|
20
|
+
|
21
|
+
def nested_hash(n)
|
22
|
+
if n == 1
|
23
|
+
{}
|
24
|
+
else
|
25
|
+
Hash.new {|h, k|
|
26
|
+
h[k] = nested_hash(n-1)
|
27
|
+
}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def nonempty_hash(h, level)
|
32
|
+
return nil if h.nil?
|
33
|
+
result = {}
|
34
|
+
h.each {|k, v|
|
35
|
+
if level == 1
|
36
|
+
result[k] = v
|
37
|
+
else
|
38
|
+
h2 = nonempty_hash(v, level-1)
|
39
|
+
if h2
|
40
|
+
result[k] = h2
|
41
|
+
end
|
42
|
+
end
|
43
|
+
}
|
44
|
+
if result.empty?
|
45
|
+
nil
|
46
|
+
else
|
47
|
+
result
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def reaction_immediate_at_beginning?(reaction)
|
52
|
+
case reaction
|
53
|
+
when :immediate
|
54
|
+
true
|
55
|
+
when :immediate_only_at_beginning
|
56
|
+
true
|
57
|
+
when :schedule
|
58
|
+
false
|
59
|
+
else
|
60
|
+
raise "unexpected reaction: #{reaction.inspect}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def reaction_immediate_at_subsequent?(reaction)
|
65
|
+
case reaction
|
66
|
+
when :immediate
|
67
|
+
true
|
68
|
+
when :immediate_only_at_beginning
|
69
|
+
false
|
70
|
+
when :schedule
|
71
|
+
false
|
72
|
+
else
|
73
|
+
raise "unexpected reaction: #{reaction.inspect}"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
data/sample/repeat.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
require 'time'
|
4
|
+
require 'fsevent'
|
5
|
+
|
6
|
+
class Repeater < FSEvent::AbstractDevice
|
7
|
+
def initialize(name, schedule)
|
8
|
+
super name
|
9
|
+
@schedule = schedule
|
10
|
+
end
|
11
|
+
|
12
|
+
def run(watched_status_change)
|
13
|
+
@framework.set_elapsed_time(1)
|
14
|
+
p @framework.current_time.iso8601(3)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
schedule = FSEvent::PeriodicSchedule.new(Time.utc(2000), 10)
|
19
|
+
repeat = Repeater.new("repeat", schedule)
|
20
|
+
|
21
|
+
fsevent = FSEvent.new(Time.utc(2000))
|
22
|
+
fsevent.register_device(repeat)
|
23
|
+
fsevent.start
|
24
|
+
|
data/sample/repeat2.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
require 'fsevent'
|
4
|
+
|
5
|
+
class Repeater < FSEvent::AbstractDevice
|
6
|
+
def initialize(name, schedule)
|
7
|
+
super name
|
8
|
+
@schedule = schedule
|
9
|
+
end
|
10
|
+
|
11
|
+
def run(watched_status_change)
|
12
|
+
p [self.name, @framework.current_time]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
repeat1 = Repeater.new("repeat1", FSEvent::PeriodicSchedule.new(Time.now, 3))
|
17
|
+
repeat2 = Repeater.new("repeat2", FSEvent::PeriodicSchedule.new(Time.now, 10))
|
18
|
+
|
19
|
+
fsevent = FSEvent.new
|
20
|
+
fsevent.register_device(repeat1)
|
21
|
+
fsevent.register_device(repeat2)
|
22
|
+
fsevent.start
|
23
|
+
|
@@ -0,0 +1,159 @@
|
|
1
|
+
# test_failsafedevice.rb --- tests for fail safe device
|
2
|
+
#
|
3
|
+
# Copyright (C) 2014 National Institute of Advanced Industrial Science and Technology (AIST)
|
4
|
+
#
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
18
|
+
require 'test/unit'
|
19
|
+
require 'fsevent'
|
20
|
+
|
21
|
+
class TestFSEventFailSafeDevice < Test::Unit::TestCase
|
22
|
+
class SrcDevice < FSEvent::AbstractDevice
|
23
|
+
def initialize(device_name, init, pairs)
|
24
|
+
super device_name
|
25
|
+
@init = init
|
26
|
+
@elapsed = 1
|
27
|
+
@schedule = pairs.map {|t, v| t-@elapsed }
|
28
|
+
@values = pairs.map {|t, v| v }
|
29
|
+
@test_result = []
|
30
|
+
end
|
31
|
+
attr_reader :test_result
|
32
|
+
|
33
|
+
def registered
|
34
|
+
set_elapsed_time(1)
|
35
|
+
define_status("s", @init)
|
36
|
+
end
|
37
|
+
|
38
|
+
def run(watched_status_change)
|
39
|
+
@test_result << [@framework.current_time, @values.first]
|
40
|
+
set_elapsed_time(@elapsed)
|
41
|
+
status_changed "s", @values.shift
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_srcdevice
|
46
|
+
t = Time.utc(2000)
|
47
|
+
fsevent = FSEvent.new(t)
|
48
|
+
srcdevice = SrcDevice.new("src", 0,
|
49
|
+
[[t+10,8],
|
50
|
+
[t+20,2],
|
51
|
+
[t+30,3],
|
52
|
+
[t+40,5],
|
53
|
+
[t+50,1]])
|
54
|
+
fsevent.register_device(srcdevice)
|
55
|
+
fsevent.start
|
56
|
+
assert_equal(
|
57
|
+
[[t+9,8],
|
58
|
+
[t+19,2],
|
59
|
+
[t+29,3],
|
60
|
+
[t+39,5],
|
61
|
+
[t+49,1]],
|
62
|
+
srcdevice.test_result)
|
63
|
+
end
|
64
|
+
|
65
|
+
class FailSafeDeviceT < FSEvent::FailSafeDevice
|
66
|
+
def registered
|
67
|
+
super
|
68
|
+
set_elapsed_time(1)
|
69
|
+
end
|
70
|
+
|
71
|
+
def run(watched_status_change)
|
72
|
+
set_elapsed_time(1)
|
73
|
+
super(watched_status_change)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
class DstDevice < FSEvent::AbstractDevice
|
78
|
+
def initialize(device_name, watchee_device_name, watchee_status)
|
79
|
+
super device_name
|
80
|
+
@watchee_device_name = watchee_device_name
|
81
|
+
@watchee_status = watchee_status
|
82
|
+
@test_result = []
|
83
|
+
end
|
84
|
+
attr_reader :test_result
|
85
|
+
|
86
|
+
def registered
|
87
|
+
super
|
88
|
+
set_elapsed_time(1)
|
89
|
+
add_watch(@watchee_device_name, @watchee_status)
|
90
|
+
end
|
91
|
+
|
92
|
+
def run(watched_status_change)
|
93
|
+
set_elapsed_time(1)
|
94
|
+
@test_result << [@framework.current_time, watched_status_change]
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_failsafe1
|
99
|
+
t = Time.utc(2000)
|
100
|
+
fsevent = FSEvent.new(t)
|
101
|
+
src1 = SrcDevice.new("src1", 0,
|
102
|
+
[[t+10,9],
|
103
|
+
[t+20,2],
|
104
|
+
[t+30,3],
|
105
|
+
[t+40,5],
|
106
|
+
[t+50,1]])
|
107
|
+
fsd = FailSafeDeviceT.new("fs",
|
108
|
+
[["s", 0, lambda {|cur, val| val }]],
|
109
|
+
"src1")
|
110
|
+
dst = DstDevice.new("dst", "fs", "s")
|
111
|
+
fsevent.register_device(src1)
|
112
|
+
fsevent.register_device(fsd)
|
113
|
+
fsevent.register_device(dst)
|
114
|
+
fsevent.start
|
115
|
+
assert_equal(
|
116
|
+
[[t + 1, {"fs"=>{"s"=>0}}],
|
117
|
+
[t + 11, {"fs"=>{"s"=>9}}],
|
118
|
+
[t + 21, {"fs"=>{"s"=>2}}],
|
119
|
+
[t + 31, {"fs"=>{"s"=>3}}],
|
120
|
+
[t + 41, {"fs"=>{"s"=>5}}],
|
121
|
+
[t + 51, {"fs"=>{"s"=>1}}]],
|
122
|
+
dst.test_result)
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_failsafe2_max
|
126
|
+
t = Time.utc(2000)
|
127
|
+
fsevent = FSEvent.new(t)
|
128
|
+
src1 = SrcDevice.new("src1", 0,
|
129
|
+
[[t+10,9],
|
130
|
+
[t+20,2],
|
131
|
+
[t+30,3],
|
132
|
+
[t+40,5],
|
133
|
+
[t+50,1]])
|
134
|
+
src2 = SrcDevice.new("src2", 0,
|
135
|
+
[[t+11,9],
|
136
|
+
[t+19,2],
|
137
|
+
[t+31,3],
|
138
|
+
[t+39,5],
|
139
|
+
[t+51,1]])
|
140
|
+
fsd = FailSafeDeviceT.new("fs",
|
141
|
+
[["s", 0, :max]],
|
142
|
+
"src1", "src2")
|
143
|
+
dst = DstDevice.new("dst", "fs", "s")
|
144
|
+
fsevent.register_device(src1)
|
145
|
+
fsevent.register_device(src2)
|
146
|
+
fsevent.register_device(fsd)
|
147
|
+
fsevent.register_device(dst)
|
148
|
+
fsevent.start
|
149
|
+
assert_equal(
|
150
|
+
[[t + 1, {"fs"=>{"s"=>0}}],
|
151
|
+
[t + 10+1, {"fs"=>{"s"=>9}}],
|
152
|
+
[t + 20+1, {"fs"=>{"s"=>2}}],
|
153
|
+
[t + 30+1, {"fs"=>{"s"=>3}}],
|
154
|
+
[t + 39+1, {"fs"=>{"s"=>5}}],
|
155
|
+
[t + 51+1, {"fs"=>{"s"=>1}}]],
|
156
|
+
dst.test_result)
|
157
|
+
end
|
158
|
+
|
159
|
+
end
|