Module: BitFlipper
- Defined in:
- lib/corruption_monkey.rb,
lib/corruption_monkey/version.rb
Defined Under Namespace
Modules: CLI
Constant Summary collapse
- BitOutOfBounds =
Class.new(Exception)
- VERSION =
'0.1.2'
Class Method Summary collapse
- .flip!(target, bit:, logger: Logger.new(nil)) ⇒ Object
- .flip_in_range(target, percentile:, logger: Logger.new(nil)) ⇒ Object
- .out_of_range(file, bit) ⇒ Object
- .random_bit_flip(target, logger: Logger.new(nil)) ⇒ Object
- .size_in_bits(file) ⇒ Object
Class Method Details
.flip!(target, bit:, logger: Logger.new(nil)) ⇒ Object
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/corruption_monkey.rb', line 7 def self.flip!(target, bit:, logger: Logger.new(nil)) logger.debug "going to flip bit with index=#{bit}" flip_byte, flip_bit = bit.divmod(8) logger.debug "computed [byte, bit]=#{[flip_byte, flip_bit]}" file = File.open(target, 'r+') file.seek(flip_byte, 0) byte = file.read(1) if byte.nil? || out_of_range(target, bit) raise BitOutOfBounds, "#{bit} is bigger than the offset=#{size_in_bits(target)}" end new_byte = [byte.unpack('c').first ^ (1 << flip_bit)].pack('c') logger.debug "readed byte: `#{byte}`: #{byte.unpack('b*').first}" logger.debug "writing byte: `#{new_byte}` #{new_byte.unpack('b*').first}" file.seek(-1, IO::SEEK_CUR) file.write(new_byte) file.fsync file.close end |
.flip_in_range(target, percentile:, logger: Logger.new(nil)) ⇒ Object
40 41 42 43 44 45 46 47 48 49 |
# File 'lib/corruption_monkey.rb', line 40 def self.flip_in_range(target, percentile:, logger: Logger.new(nil)) # TODO(javierhonduco): Improve error checking (╯ರ ~ ರ) bit_to_flip = (size_in_bits(target) * percentile/101.0).to_i if out_of_range(target, bit_to_flip) raise IndexError, "percentile=#{percentile} not in range" end flip!(target, bit: bit_to_flip, logger: logger) end |
.out_of_range(file, bit) ⇒ Object
55 56 57 |
# File 'lib/corruption_monkey.rb', line 55 def self.out_of_range(file, bit) bit < 0 || bit > size_in_bits(file) end |
.random_bit_flip(target, logger: Logger.new(nil)) ⇒ Object
35 36 37 38 |
# File 'lib/corruption_monkey.rb', line 35 def self.random_bit_flip(target, logger: Logger.new(nil)) computed_bit = rand(0...size_in_bits(target)) flip!(target, bit: computed_bit, logger: logger) end |
.size_in_bits(file) ⇒ Object
51 52 53 |
# File 'lib/corruption_monkey.rb', line 51 def self.size_in_bits(file) File.size(file) * 8 end |