]> arthur.barton.de Git - bup.git/commitdiff
cmd-damage: a program for randomly corrupting file contents.
authorAvery Pennarun <apenwarr@gmail.com>
Sat, 30 Jan 2010 21:59:44 +0000 (16:59 -0500)
committerAvery Pennarun <apenwarr@gmail.com>
Sun, 31 Jan 2010 01:31:01 +0000 (20:31 -0500)
Sure, that *sounds* like a terrible idea.  But it's fun for testing recovery
algorithms, at least.

Makefile
cmd-damage.py [new file with mode: 0755]

index 568ececc5056ba2e2d8a8f9c850fbdf9d38e01b9..19302161c9bbd673dc15c01ddbc171e1881ef5ed 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -20,7 +20,7 @@ endif
 default: all
 
 all: bup-split bup-join bup-save bup-init bup-server bup-index bup-tick \
-       bup-midx bup-fuse bup-ls \
+       bup-midx bup-fuse bup-ls bup-damage \
        bup memtest randomgen$(EXT) _hashsplit$(SOEXT)
 
 randomgen$(EXT): randomgen.o
diff --git a/cmd-damage.py b/cmd-damage.py
new file mode 100755 (executable)
index 0000000..1ca2cde
--- /dev/null
@@ -0,0 +1,57 @@
+#!/usr/bin/env python
+import sys, os, random
+import options
+from helpers import *
+
+
+def randblock(n):
+    l = []
+    for i in xrange(n):
+        l.append(chr(random.randrange(0,256)))
+    return ''.join(l)
+
+
+optspec = """
+bup damage [-n count] [-s maxsize] [-S seed] <filenames...>
+--
+   WARNING: THIS COMMAND IS EXTREMELY DANGEROUS
+n,num=   number of blocks to damage
+s,size=  maximum size of each damaged block
+percent= maximum size of each damaged block (as a percent of entire file)
+equal    spread damage evenly throughout the file
+S,seed=  random number seed (for repeatable tests)
+"""
+o = options.Options('bup damage', optspec)
+(opt, flags, extra) = o.parse(sys.argv[1:])
+
+if not extra:
+    o.usage()
+
+if opt.seed != None:
+    random.seed(opt.seed)
+
+for name in extra:
+    log('Damaging "%s"...\n' % name)
+    f = open(name, 'r+b')
+    st = os.fstat(f.fileno())
+    size = st.st_size
+    if opt.percent or opt.size:
+        ms1 = int(float(opt.percent or 0)/100.0*size) or size
+        ms2 = opt.size or size
+        maxsize = min(ms1, ms2)
+    else:
+        maxsize = 1
+    chunks = opt.num or 10
+    chunksize = size/chunks
+    for r in range(chunks):
+        sz = random.randrange(1, maxsize+1)
+        if sz > size:
+            sz = size
+        if opt.equal:
+            ofs = r*chunksize
+        else:
+            ofs = random.randrange(0, size - sz + 1)
+        log('  %6d bytes at %d\n' % (sz, ofs))
+        f.seek(ofs)
+        f.write(randblock(sz))
+    f.close()