xref: /dragonfly/contrib/cryptsetup/tests/fileDiffer.py (revision 86d7f5d305c6adaa56ff4582ece9859d73106103)
1#!/usr/bin/env 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
13import sys
14
15class changes:
16          pass
17
18def 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
50def mode(i):
51          for c in changelist:
52                    if i >= c.starts and i<=c.ends:
53                              return c
54def 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
63aFile = open(aFileName,'r')
64bFile = open(bFileName,'r')
65
66aString = aFile.read()
67bString = bFile.read()
68
69if len(aString) != len(bString):
70          sys.exit("Mismatch different file sizes")
71
72fileLen = len(aString)
73fileLen10th = fileLen/10
74
75# Create a catch all entry
76changelist[-1].ends = fileLen
77
78print "Changes list: (FORBIDDEN default)"
79print "start\tend\tmode\t\tstrictness"
80for 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
87filepos = 0
88fileLen10thC = 0
89print "[..........]"
90sys.stdout.write("[")
91sys.stdout.flush()
92
93modeNotTrivial = 1
94while 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
119for 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
129print ".] - everything ok"
130