lib/rfuzz/pushbackio.rb in rfuzz-0.8 vs lib/rfuzz/pushbackio.rb in rfuzz-0.9
- old
+ new
@@ -9,26 +9,37 @@
attr_accessor :secondary
def initialize(secondary)
@secondary = secondary
@buffer = StringIO.new
+ @die_after = rand($io_death_count) if $io_death_count
end
+ def random_death
+ if $io_death_count
+ @die_after -= 1
+ close if @die_after <= 0
+ end
+ end
+
# Pushes the given string content back onto the stream for the
# next read to handle.
def push(content)
+ random_death
if content.length > 0
@buffer.write(content)
end
end
def pop(n)
+ random_death
@buffer.rewind
@buffer.read(n) || ""
end
def reset
+ random_death
@buffer.string = @buffer.read # reset out internal buffer
end
# First does a read from the internal buffer, and then appends anything
# needed from the secondary IO to complete the request. The return
@@ -36,10 +47,11 @@
# a string of length 0 then there is nothing to read from the buffer (most
# likely closed). It will also avoid reading from a secondary that's closed.
#
# If partial==true then readpartial is used instead.
def read(n, partial=false)
+ random_death
r = pop(n)
needs = n - r.length
if needs > 0
sec = ""
@@ -47,11 +59,11 @@
begin
protect do
sec = @secondary.readpartial(needs)
end
rescue EOFError
- # TODO: notify closed? error?
+ close
end
else
protect { sec = @secondary.read(needs)}
end
@@ -66,18 +78,20 @@
reset
return r
end
def flush
+ random_death
protect { @secondary.flush }
end
def write(content)
+ random_death
protect { @secondary.write(content) }
end
def close
- protect { @secondary.close }
+ @secondary.close rescue nil
end
def protect
if !@secondary.closed?
yield