43f49873a60e5b0c726d4040331ce12a57a11dc8
[dragonfly.git] / contrib / cryptsetup / tests / fileDiffer.py
1 #!/usr/bin/python
2
3 #
4 # Usage: fileDiffer <afile> <bfile> <list of disk changes>
5
6
7 # LUKS 
8 # quick regression test suite
9 # Tests LUKS images for changes at certain disk offsets
10 #
11 # Does fast python code has to look ugly or is it just me?
12
13 import sys
14
15 class changes:
16         pass
17
18 def parseArgs(args):
19         aFileName = args[1]
20         bFileName = args[2]
21         changelist = []
22         args[0:3] = []
23         for i in args:
24                 mychanges = changes();
25                 if i.startswith('A'):
26                         mychanges.mode = 'ALLOWED'
27                 if i.startswith('R'):
28                         mychanges.mode = 'REQUIRED'
29                         mychanges.strictness = 'RANDOM'
30                 if i.startswith('S'):
31                         mychanges.mode = 'REQUIRED'
32                         mychanges.strictness = 'SEMANTIC'
33                 
34                 dashIndex = i.find('-')
35                 if dashIndex == -1:                     
36                         mychanges.starts = int(i[1:])
37                         mychanges.ends = mychanges.starts
38                 else:
39                         mychanges.starts = int(i[1:dashIndex])
40                         mychanges.ends = int(i[dashIndex+1:])
41                 mychanges.miss = 0
42                 changelist.append(mychanges)
43         mychanges = changes();
44         mychanges.starts = 0
45 #       mychanges.ends will be fixed later
46         mychanges.mode = 'FORBIDDEN'    
47         changelist.append(mychanges)
48         return [aFileName, bFileName, changelist]
49
50 def mode(i):
51         for c in changelist:
52                 if i >= c.starts and i<=c.ends:
53                         return c
54 def cleanchanges(i):
55         newchangelist=[]        
56         for c in changelist:
57                 if i <= c.starts or i <= c.ends:
58                         newchangelist.append(c)
59         return newchangelist
60
61 [aFileName, bFileName, changelist] = parseArgs(sys.argv)
62
63 aFile = open(aFileName,'r')
64 bFile = open(bFileName,'r')
65
66 aString = aFile.read()
67 bString = bFile.read()
68
69 if len(aString) != len(bString): 
70         sys.exit("Mismatch different file sizes")
71
72 fileLen = len(aString)
73 fileLen10th = fileLen/10
74
75 # Create a catch all entry
76 changelist[-1].ends = fileLen
77
78 print "Changes list: (FORBIDDEN default)"
79 print "start\tend\tmode\t\tstrictness"
80 for i in changelist:
81         if i.mode == 'REQUIRED':
82                 print "%d\t%d\t%s\t%s" % (i.starts, i.ends, i.mode, i.strictness)
83         else:
84                 print "%d\t%d\t%s" % (i.starts, i.ends, i.mode)
85
86
87 filepos = 0
88 fileLen10thC = 0
89 print "[..........]"
90 sys.stdout.write("[")
91 sys.stdout.flush()
92
93 modeNotTrivial = 1
94 while filepos < fileLen:
95
96         if modeNotTrivial == 1:
97                 c = mode(filepos)
98 #       print (filepos, c.mode)
99         if c.mode == 'REQUIRED':
100                 if aString[filepos] == bString[filepos]:
101                         c.miss = c.miss + 1
102         else:
103                 if aString[filepos] != bString[filepos] and c.mode != 'ALLOWED':
104                         sys.exit("Mismatch at %d: change forbidden" % filepos)
105
106         # Do some maintaince, print progress bar, and clean changelist
107         #
108         # Maintaining two counters appears to be faster than modulo operation
109         if fileLen10thC == fileLen10th:
110                 fileLen10thC = 0
111                 sys.stdout.write(".")
112                 sys.stdout.flush()
113                 changelist = cleanchanges(filepos)
114                 if len(changelist) == 1:
115                         modeNotTrivial = 0
116         filepos = filepos + 1
117         fileLen10thC = fileLen10thC + 1
118
119 for c in changelist:
120         if c.mode == 'REQUIRED':
121                 if c.strictness == 'SEMANTIC' and c.miss == (c.ends-c.starts+1):
122                         sys.exit("Mismatch: not even a single change in region %d-%d." % (c.starts, c.ends))
123                 # This is not correct. We should do a statistical test
124                 # of the sampled data against the hypothetical distribution
125                 # of collision. Chi-Square Test.
126                 if c.strictness == 'RANDOM' and c.miss == (c.ends-c.starts+1):
127                         sys.exit("Mismatch: not even a single change in region %d-%d." % (c.starts, c.ends))
128
129 print ".] - everything ok"